Commit b9a0f872a9ff3b5074c74da98052b5205929b560

Authored by Kashyap, Desai
Committed by James Bottomley
1 parent cc7e9f5f99

[SCSI] mptfusion: Added missing reset for ioc_reset_in_progress in SoftReset

Added missing part which will reset ioc_reset_in_progress before returning from SoftResetHandler.

Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>

Showing 1 changed file with 1 additions and 0 deletions Inline Diff

drivers/message/fusion/mptbase.c
1 /* 1 /*
2 * linux/drivers/message/fusion/mptbase.c 2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple 3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers. 4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s) 5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware. 6 * running LSI Fusion MPT (Message Passing Technology) firmware.
7 * 7 *
8 * Copyright (c) 1999-2008 LSI Corporation 8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com) 9 * (mailto:DL-MPTFusionLinux@lsi.com)
10 * 10 *
11 */ 11 */
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
13 /* 13 /*
14 This program is free software; you can redistribute it and/or modify 14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by 15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License. 16 the Free Software Foundation; version 2 of the License.
17 17
18 This program is distributed in the hope that it will be useful, 18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details. 21 GNU General Public License for more details.
22 22
23 NO WARRANTY 23 NO WARRANTY
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and 28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its 29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to 30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data, 31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations. 32 programs or equipment, and unavailability or interruption of operations.
33 33
34 DISCLAIMER OF LIABILITY 34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
42 42
43 You should have received a copy of the GNU General Public License 43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software 44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
46 */ 46 */
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48 48
49 #include <linux/kernel.h> 49 #include <linux/kernel.h>
50 #include <linux/module.h> 50 #include <linux/module.h>
51 #include <linux/errno.h> 51 #include <linux/errno.h>
52 #include <linux/init.h> 52 #include <linux/init.h>
53 #include <linux/slab.h> 53 #include <linux/slab.h>
54 #include <linux/types.h> 54 #include <linux/types.h>
55 #include <linux/pci.h> 55 #include <linux/pci.h>
56 #include <linux/kdev_t.h> 56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h> 57 #include <linux/blkdev.h>
58 #include <linux/delay.h> 58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */ 59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h> 60 #include <linux/dma-mapping.h>
61 #include <asm/io.h> 61 #include <asm/io.h>
62 #ifdef CONFIG_MTRR 62 #ifdef CONFIG_MTRR
63 #include <asm/mtrr.h> 63 #include <asm/mtrr.h>
64 #endif 64 #endif
65 65
66 #include "mptbase.h" 66 #include "mptbase.h"
67 #include "lsi/mpi_log_fc.h" 67 #include "lsi/mpi_log_fc.h"
68 68
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver" 70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON 71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase" 72 #define MYNAM "mptbase"
73 73
74 MODULE_AUTHOR(MODULEAUTHOR); 74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME); 75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL"); 76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION); 77 MODULE_VERSION(my_VERSION);
78 78
79 /* 79 /*
80 * cmd line parameters 80 * cmd line parameters
81 */ 81 */
82 82
83 static int mpt_msi_enable_spi; 83 static int mpt_msi_enable_spi;
84 module_param(mpt_msi_enable_spi, int, 0); 84 module_param(mpt_msi_enable_spi, int, 0);
85 MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \ 85 MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
86 controllers (default=0)"); 86 controllers (default=0)");
87 87
88 static int mpt_msi_enable_fc; 88 static int mpt_msi_enable_fc;
89 module_param(mpt_msi_enable_fc, int, 0); 89 module_param(mpt_msi_enable_fc, int, 0);
90 MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \ 90 MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
91 controllers (default=0)"); 91 controllers (default=0)");
92 92
93 static int mpt_msi_enable_sas; 93 static int mpt_msi_enable_sas;
94 module_param(mpt_msi_enable_sas, int, 0); 94 module_param(mpt_msi_enable_sas, int, 0);
95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ 95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
96 controllers (default=0)"); 96 controllers (default=0)");
97 97
98 98
99 static int mpt_channel_mapping; 99 static int mpt_channel_mapping;
100 module_param(mpt_channel_mapping, int, 0); 100 module_param(mpt_channel_mapping, int, 0);
101 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)"); 101 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
102 102
103 static int mpt_debug_level; 103 static int mpt_debug_level;
104 static int mpt_set_debug_level(const char *val, struct kernel_param *kp); 104 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
105 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int, 105 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
106 &mpt_debug_level, 0600); 106 &mpt_debug_level, 0600);
107 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \ 107 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
108 - (default=0)"); 108 - (default=0)");
109 109
110 int mpt_fwfault_debug; 110 int mpt_fwfault_debug;
111 EXPORT_SYMBOL(mpt_fwfault_debug); 111 EXPORT_SYMBOL(mpt_fwfault_debug);
112 module_param_call(mpt_fwfault_debug, param_set_int, param_get_int, 112 module_param_call(mpt_fwfault_debug, param_set_int, param_get_int,
113 &mpt_fwfault_debug, 0600); 113 &mpt_fwfault_debug, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault" 114 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)"); 115 " and halt Firmware on fault - (default=0)");
116 116
117 117
118 118
119 #ifdef MFCNT 119 #ifdef MFCNT
120 static int mfcounter = 0; 120 static int mfcounter = 0;
121 #define PRINT_MF_COUNT 20000 121 #define PRINT_MF_COUNT 20000
122 #endif 122 #endif
123 123
124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
125 /* 125 /*
126 * Public data... 126 * Public data...
127 */ 127 */
128 128
129 #define WHOINIT_UNKNOWN 0xAA 129 #define WHOINIT_UNKNOWN 0xAA
130 130
131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
132 /* 132 /*
133 * Private data... 133 * Private data...
134 */ 134 */
135 /* Adapter link list */ 135 /* Adapter link list */
136 LIST_HEAD(ioc_list); 136 LIST_HEAD(ioc_list);
137 /* Callback lookup table */ 137 /* Callback lookup table */
138 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS]; 138 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
139 /* Protocol driver class lookup table */ 139 /* Protocol driver class lookup table */
140 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS]; 140 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
141 /* Event handler lookup table */ 141 /* Event handler lookup table */
142 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 142 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
143 /* Reset handler lookup table */ 143 /* Reset handler lookup table */
144 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 144 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
145 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 145 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
146 146
147 #ifdef CONFIG_PROC_FS 147 #ifdef CONFIG_PROC_FS
148 static struct proc_dir_entry *mpt_proc_root_dir; 148 static struct proc_dir_entry *mpt_proc_root_dir;
149 #endif 149 #endif
150 150
151 /* 151 /*
152 * Driver Callback Index's 152 * Driver Callback Index's
153 */ 153 */
154 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS; 154 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
155 static u8 last_drv_idx; 155 static u8 last_drv_idx;
156 156
157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
158 /* 158 /*
159 * Forward protos... 159 * Forward protos...
160 */ 160 */
161 static irqreturn_t mpt_interrupt(int irq, void *bus_id); 161 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
162 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, 162 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
163 MPT_FRAME_HDR *reply); 163 MPT_FRAME_HDR *reply);
164 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, 164 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
165 u32 *req, int replyBytes, u16 *u16reply, int maxwait, 165 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
166 int sleepFlag); 166 int sleepFlag);
167 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag); 167 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
168 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev); 168 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
169 static void mpt_adapter_disable(MPT_ADAPTER *ioc); 169 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
170 static void mpt_adapter_dispose(MPT_ADAPTER *ioc); 170 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
171 171
172 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc); 172 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
173 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag); 173 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
174 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason); 174 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
175 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag); 175 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
176 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); 176 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
177 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag); 177 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
178 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag); 178 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
179 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag); 179 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
180 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag); 180 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
181 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag); 181 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
182 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag); 182 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
183 static int PrimeIocFifos(MPT_ADAPTER *ioc); 183 static int PrimeIocFifos(MPT_ADAPTER *ioc);
184 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 184 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 185 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 186 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
187 static int GetLanConfigPages(MPT_ADAPTER *ioc); 187 static int GetLanConfigPages(MPT_ADAPTER *ioc);
188 static int GetIoUnitPage2(MPT_ADAPTER *ioc); 188 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
189 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 189 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
190 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); 190 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
191 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); 191 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
192 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); 192 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
193 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); 193 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
194 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc); 194 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
195 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, 195 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
196 int sleepFlag); 196 int sleepFlag);
197 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); 197 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
198 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag); 198 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
199 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init); 199 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
200 200
201 #ifdef CONFIG_PROC_FS 201 #ifdef CONFIG_PROC_FS
202 static int procmpt_summary_read(char *buf, char **start, off_t offset, 202 static int procmpt_summary_read(char *buf, char **start, off_t offset,
203 int request, int *eof, void *data); 203 int request, int *eof, void *data);
204 static int procmpt_version_read(char *buf, char **start, off_t offset, 204 static int procmpt_version_read(char *buf, char **start, off_t offset,
205 int request, int *eof, void *data); 205 int request, int *eof, void *data);
206 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset, 206 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
207 int request, int *eof, void *data); 207 int request, int *eof, void *data);
208 #endif 208 #endif
209 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); 209 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
210 210
211 static int ProcessEventNotification(MPT_ADAPTER *ioc, 211 static int ProcessEventNotification(MPT_ADAPTER *ioc,
212 EventNotificationReply_t *evReply, int *evHandlers); 212 EventNotificationReply_t *evReply, int *evHandlers);
213 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 213 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
214 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 214 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
215 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); 215 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
216 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); 216 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
217 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 217 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
218 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc); 218 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
219 219
220 /* module entry point */ 220 /* module entry point */
221 static int __init fusion_init (void); 221 static int __init fusion_init (void);
222 static void __exit fusion_exit (void); 222 static void __exit fusion_exit (void);
223 223
224 #define CHIPREG_READ32(addr) readl_relaxed(addr) 224 #define CHIPREG_READ32(addr) readl_relaxed(addr)
225 #define CHIPREG_READ32_dmasync(addr) readl(addr) 225 #define CHIPREG_READ32_dmasync(addr) readl(addr)
226 #define CHIPREG_WRITE32(addr,val) writel(val, addr) 226 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
227 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr) 227 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
228 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr) 228 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
229 229
230 static void 230 static void
231 pci_disable_io_access(struct pci_dev *pdev) 231 pci_disable_io_access(struct pci_dev *pdev)
232 { 232 {
233 u16 command_reg; 233 u16 command_reg;
234 234
235 pci_read_config_word(pdev, PCI_COMMAND, &command_reg); 235 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
236 command_reg &= ~1; 236 command_reg &= ~1;
237 pci_write_config_word(pdev, PCI_COMMAND, command_reg); 237 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
238 } 238 }
239 239
240 static void 240 static void
241 pci_enable_io_access(struct pci_dev *pdev) 241 pci_enable_io_access(struct pci_dev *pdev)
242 { 242 {
243 u16 command_reg; 243 u16 command_reg;
244 244
245 pci_read_config_word(pdev, PCI_COMMAND, &command_reg); 245 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
246 command_reg |= 1; 246 command_reg |= 1;
247 pci_write_config_word(pdev, PCI_COMMAND, command_reg); 247 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
248 } 248 }
249 249
250 static int mpt_set_debug_level(const char *val, struct kernel_param *kp) 250 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
251 { 251 {
252 int ret = param_set_int(val, kp); 252 int ret = param_set_int(val, kp);
253 MPT_ADAPTER *ioc; 253 MPT_ADAPTER *ioc;
254 254
255 if (ret) 255 if (ret)
256 return ret; 256 return ret;
257 257
258 list_for_each_entry(ioc, &ioc_list, list) 258 list_for_each_entry(ioc, &ioc_list, list)
259 ioc->debug_level = mpt_debug_level; 259 ioc->debug_level = mpt_debug_level;
260 return 0; 260 return 0;
261 } 261 }
262 262
263 /** 263 /**
264 * mpt_get_cb_idx - obtain cb_idx for registered driver 264 * mpt_get_cb_idx - obtain cb_idx for registered driver
265 * @dclass: class driver enum 265 * @dclass: class driver enum
266 * 266 *
267 * Returns cb_idx, or zero means it wasn't found 267 * Returns cb_idx, or zero means it wasn't found
268 **/ 268 **/
269 static u8 269 static u8
270 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass) 270 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
271 { 271 {
272 u8 cb_idx; 272 u8 cb_idx;
273 273
274 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) 274 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
275 if (MptDriverClass[cb_idx] == dclass) 275 if (MptDriverClass[cb_idx] == dclass)
276 return cb_idx; 276 return cb_idx;
277 return 0; 277 return 0;
278 } 278 }
279 279
280 /** 280 /**
281 * mpt_is_discovery_complete - determine if discovery has completed 281 * mpt_is_discovery_complete - determine if discovery has completed
282 * @ioc: per adatper instance 282 * @ioc: per adatper instance
283 * 283 *
284 * Returns 1 when discovery completed, else zero. 284 * Returns 1 when discovery completed, else zero.
285 */ 285 */
286 static int 286 static int
287 mpt_is_discovery_complete(MPT_ADAPTER *ioc) 287 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
288 { 288 {
289 ConfigExtendedPageHeader_t hdr; 289 ConfigExtendedPageHeader_t hdr;
290 CONFIGPARMS cfg; 290 CONFIGPARMS cfg;
291 SasIOUnitPage0_t *buffer; 291 SasIOUnitPage0_t *buffer;
292 dma_addr_t dma_handle; 292 dma_addr_t dma_handle;
293 int rc = 0; 293 int rc = 0;
294 294
295 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t)); 295 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
296 memset(&cfg, 0, sizeof(CONFIGPARMS)); 296 memset(&cfg, 0, sizeof(CONFIGPARMS));
297 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION; 297 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
298 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 298 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
299 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 299 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
300 cfg.cfghdr.ehdr = &hdr; 300 cfg.cfghdr.ehdr = &hdr;
301 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 301 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
302 302
303 if ((mpt_config(ioc, &cfg))) 303 if ((mpt_config(ioc, &cfg)))
304 goto out; 304 goto out;
305 if (!hdr.ExtPageLength) 305 if (!hdr.ExtPageLength)
306 goto out; 306 goto out;
307 307
308 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 308 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
309 &dma_handle); 309 &dma_handle);
310 if (!buffer) 310 if (!buffer)
311 goto out; 311 goto out;
312 312
313 cfg.physAddr = dma_handle; 313 cfg.physAddr = dma_handle;
314 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 314 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
315 315
316 if ((mpt_config(ioc, &cfg))) 316 if ((mpt_config(ioc, &cfg)))
317 goto out_free_consistent; 317 goto out_free_consistent;
318 318
319 if (!(buffer->PhyData[0].PortFlags & 319 if (!(buffer->PhyData[0].PortFlags &
320 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS)) 320 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
321 rc = 1; 321 rc = 1;
322 322
323 out_free_consistent: 323 out_free_consistent:
324 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 324 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
325 buffer, dma_handle); 325 buffer, dma_handle);
326 out: 326 out:
327 return rc; 327 return rc;
328 } 328 }
329 329
330 /** 330 /**
331 * mpt_fault_reset_work - work performed on workq after ioc fault 331 * mpt_fault_reset_work - work performed on workq after ioc fault
332 * @work: input argument, used to derive ioc 332 * @work: input argument, used to derive ioc
333 * 333 *
334 **/ 334 **/
335 static void 335 static void
336 mpt_fault_reset_work(struct work_struct *work) 336 mpt_fault_reset_work(struct work_struct *work)
337 { 337 {
338 MPT_ADAPTER *ioc = 338 MPT_ADAPTER *ioc =
339 container_of(work, MPT_ADAPTER, fault_reset_work.work); 339 container_of(work, MPT_ADAPTER, fault_reset_work.work);
340 u32 ioc_raw_state; 340 u32 ioc_raw_state;
341 int rc; 341 int rc;
342 unsigned long flags; 342 unsigned long flags;
343 343
344 if (ioc->ioc_reset_in_progress || !ioc->active) 344 if (ioc->ioc_reset_in_progress || !ioc->active)
345 goto out; 345 goto out;
346 346
347 ioc_raw_state = mpt_GetIocState(ioc, 0); 347 ioc_raw_state = mpt_GetIocState(ioc, 0);
348 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 348 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
349 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", 349 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
350 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); 350 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
351 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", 351 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
352 ioc->name, __func__); 352 ioc->name, __func__);
353 rc = mpt_HardResetHandler(ioc, CAN_SLEEP); 353 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
354 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name, 354 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
355 __func__, (rc == 0) ? "success" : "failed"); 355 __func__, (rc == 0) ? "success" : "failed");
356 ioc_raw_state = mpt_GetIocState(ioc, 0); 356 ioc_raw_state = mpt_GetIocState(ioc, 0);
357 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) 357 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
358 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " 358 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
359 "reset (%04xh)\n", ioc->name, ioc_raw_state & 359 "reset (%04xh)\n", ioc->name, ioc_raw_state &
360 MPI_DOORBELL_DATA_MASK); 360 MPI_DOORBELL_DATA_MASK);
361 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) { 361 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
362 if ((mpt_is_discovery_complete(ioc))) { 362 if ((mpt_is_discovery_complete(ioc))) {
363 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing " 363 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
364 "discovery_quiesce_io flag\n", ioc->name)); 364 "discovery_quiesce_io flag\n", ioc->name));
365 ioc->sas_discovery_quiesce_io = 0; 365 ioc->sas_discovery_quiesce_io = 0;
366 } 366 }
367 } 367 }
368 368
369 out: 369 out:
370 /* 370 /*
371 * Take turns polling alternate controller 371 * Take turns polling alternate controller
372 */ 372 */
373 if (ioc->alt_ioc) 373 if (ioc->alt_ioc)
374 ioc = ioc->alt_ioc; 374 ioc = ioc->alt_ioc;
375 375
376 /* rearm the timer */ 376 /* rearm the timer */
377 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 377 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
378 if (ioc->reset_work_q) 378 if (ioc->reset_work_q)
379 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, 379 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
380 msecs_to_jiffies(MPT_POLLING_INTERVAL)); 380 msecs_to_jiffies(MPT_POLLING_INTERVAL));
381 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 381 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
382 } 382 }
383 383
384 384
385 /* 385 /*
386 * Process turbo (context) reply... 386 * Process turbo (context) reply...
387 */ 387 */
388 static void 388 static void
389 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) 389 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
390 { 390 {
391 MPT_FRAME_HDR *mf = NULL; 391 MPT_FRAME_HDR *mf = NULL;
392 MPT_FRAME_HDR *mr = NULL; 392 MPT_FRAME_HDR *mr = NULL;
393 u16 req_idx = 0; 393 u16 req_idx = 0;
394 u8 cb_idx; 394 u8 cb_idx;
395 395
396 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n", 396 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
397 ioc->name, pa)); 397 ioc->name, pa));
398 398
399 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) { 399 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
400 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT: 400 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
401 req_idx = pa & 0x0000FFFF; 401 req_idx = pa & 0x0000FFFF;
402 cb_idx = (pa & 0x00FF0000) >> 16; 402 cb_idx = (pa & 0x00FF0000) >> 16;
403 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 403 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
404 break; 404 break;
405 case MPI_CONTEXT_REPLY_TYPE_LAN: 405 case MPI_CONTEXT_REPLY_TYPE_LAN:
406 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER); 406 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
407 /* 407 /*
408 * Blind set of mf to NULL here was fatal 408 * Blind set of mf to NULL here was fatal
409 * after lan_reply says "freeme" 409 * after lan_reply says "freeme"
410 * Fix sort of combined with an optimization here; 410 * Fix sort of combined with an optimization here;
411 * added explicit check for case where lan_reply 411 * added explicit check for case where lan_reply
412 * was just returning 1 and doing nothing else. 412 * was just returning 1 and doing nothing else.
413 * For this case skip the callback, but set up 413 * For this case skip the callback, but set up
414 * proper mf value first here:-) 414 * proper mf value first here:-)
415 */ 415 */
416 if ((pa & 0x58000000) == 0x58000000) { 416 if ((pa & 0x58000000) == 0x58000000) {
417 req_idx = pa & 0x0000FFFF; 417 req_idx = pa & 0x0000FFFF;
418 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 418 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
419 mpt_free_msg_frame(ioc, mf); 419 mpt_free_msg_frame(ioc, mf);
420 mb(); 420 mb();
421 return; 421 return;
422 break; 422 break;
423 } 423 }
424 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa); 424 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
425 break; 425 break;
426 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET: 426 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
427 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER); 427 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
428 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa); 428 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
429 break; 429 break;
430 default: 430 default:
431 cb_idx = 0; 431 cb_idx = 0;
432 BUG(); 432 BUG();
433 } 433 }
434 434
435 /* Check for (valid) IO callback! */ 435 /* Check for (valid) IO callback! */
436 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || 436 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
437 MptCallbacks[cb_idx] == NULL) { 437 MptCallbacks[cb_idx] == NULL) {
438 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", 438 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
439 __func__, ioc->name, cb_idx); 439 __func__, ioc->name, cb_idx);
440 goto out; 440 goto out;
441 } 441 }
442 442
443 if (MptCallbacks[cb_idx](ioc, mf, mr)) 443 if (MptCallbacks[cb_idx](ioc, mf, mr))
444 mpt_free_msg_frame(ioc, mf); 444 mpt_free_msg_frame(ioc, mf);
445 out: 445 out:
446 mb(); 446 mb();
447 } 447 }
448 448
449 static void 449 static void
450 mpt_reply(MPT_ADAPTER *ioc, u32 pa) 450 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
451 { 451 {
452 MPT_FRAME_HDR *mf; 452 MPT_FRAME_HDR *mf;
453 MPT_FRAME_HDR *mr; 453 MPT_FRAME_HDR *mr;
454 u16 req_idx; 454 u16 req_idx;
455 u8 cb_idx; 455 u8 cb_idx;
456 int freeme; 456 int freeme;
457 457
458 u32 reply_dma_low; 458 u32 reply_dma_low;
459 u16 ioc_stat; 459 u16 ioc_stat;
460 460
461 /* non-TURBO reply! Hmmm, something may be up... 461 /* non-TURBO reply! Hmmm, something may be up...
462 * Newest turbo reply mechanism; get address 462 * Newest turbo reply mechanism; get address
463 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)! 463 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
464 */ 464 */
465 465
466 /* Map DMA address of reply header to cpu address. 466 /* Map DMA address of reply header to cpu address.
467 * pa is 32 bits - but the dma address may be 32 or 64 bits 467 * pa is 32 bits - but the dma address may be 32 or 64 bits
468 * get offset based only only the low addresses 468 * get offset based only only the low addresses
469 */ 469 */
470 470
471 reply_dma_low = (pa <<= 1); 471 reply_dma_low = (pa <<= 1);
472 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames + 472 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
473 (reply_dma_low - ioc->reply_frames_low_dma)); 473 (reply_dma_low - ioc->reply_frames_low_dma));
474 474
475 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx); 475 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
476 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx; 476 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
477 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 477 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
478 478
479 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n", 479 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
480 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function)); 480 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
481 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr); 481 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
482 482
483 /* Check/log IOC log info 483 /* Check/log IOC log info
484 */ 484 */
485 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus); 485 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
486 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 486 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
487 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo); 487 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
488 if (ioc->bus_type == FC) 488 if (ioc->bus_type == FC)
489 mpt_fc_log_info(ioc, log_info); 489 mpt_fc_log_info(ioc, log_info);
490 else if (ioc->bus_type == SPI) 490 else if (ioc->bus_type == SPI)
491 mpt_spi_log_info(ioc, log_info); 491 mpt_spi_log_info(ioc, log_info);
492 else if (ioc->bus_type == SAS) 492 else if (ioc->bus_type == SAS)
493 mpt_sas_log_info(ioc, log_info); 493 mpt_sas_log_info(ioc, log_info);
494 } 494 }
495 495
496 if (ioc_stat & MPI_IOCSTATUS_MASK) 496 if (ioc_stat & MPI_IOCSTATUS_MASK)
497 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf); 497 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
498 498
499 /* Check for (valid) IO callback! */ 499 /* Check for (valid) IO callback! */
500 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || 500 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
501 MptCallbacks[cb_idx] == NULL) { 501 MptCallbacks[cb_idx] == NULL) {
502 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", 502 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
503 __func__, ioc->name, cb_idx); 503 __func__, ioc->name, cb_idx);
504 freeme = 0; 504 freeme = 0;
505 goto out; 505 goto out;
506 } 506 }
507 507
508 freeme = MptCallbacks[cb_idx](ioc, mf, mr); 508 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
509 509
510 out: 510 out:
511 /* Flush (non-TURBO) reply with a WRITE! */ 511 /* Flush (non-TURBO) reply with a WRITE! */
512 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa); 512 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
513 513
514 if (freeme) 514 if (freeme)
515 mpt_free_msg_frame(ioc, mf); 515 mpt_free_msg_frame(ioc, mf);
516 mb(); 516 mb();
517 } 517 }
518 518
519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
520 /** 520 /**
521 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler. 521 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
522 * @irq: irq number (not used) 522 * @irq: irq number (not used)
523 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure 523 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
524 * 524 *
525 * This routine is registered via the request_irq() kernel API call, 525 * This routine is registered via the request_irq() kernel API call,
526 * and handles all interrupts generated from a specific MPT adapter 526 * and handles all interrupts generated from a specific MPT adapter
527 * (also referred to as a IO Controller or IOC). 527 * (also referred to as a IO Controller or IOC).
528 * This routine must clear the interrupt from the adapter and does 528 * This routine must clear the interrupt from the adapter and does
529 * so by reading the reply FIFO. Multiple replies may be processed 529 * so by reading the reply FIFO. Multiple replies may be processed
530 * per single call to this routine. 530 * per single call to this routine.
531 * 531 *
532 * This routine handles register-level access of the adapter but 532 * This routine handles register-level access of the adapter but
533 * dispatches (calls) a protocol-specific callback routine to handle 533 * dispatches (calls) a protocol-specific callback routine to handle
534 * the protocol-specific details of the MPT request completion. 534 * the protocol-specific details of the MPT request completion.
535 */ 535 */
536 static irqreturn_t 536 static irqreturn_t
537 mpt_interrupt(int irq, void *bus_id) 537 mpt_interrupt(int irq, void *bus_id)
538 { 538 {
539 MPT_ADAPTER *ioc = bus_id; 539 MPT_ADAPTER *ioc = bus_id;
540 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); 540 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
541 541
542 if (pa == 0xFFFFFFFF) 542 if (pa == 0xFFFFFFFF)
543 return IRQ_NONE; 543 return IRQ_NONE;
544 544
545 /* 545 /*
546 * Drain the reply FIFO! 546 * Drain the reply FIFO!
547 */ 547 */
548 do { 548 do {
549 if (pa & MPI_ADDRESS_REPLY_A_BIT) 549 if (pa & MPI_ADDRESS_REPLY_A_BIT)
550 mpt_reply(ioc, pa); 550 mpt_reply(ioc, pa);
551 else 551 else
552 mpt_turbo_reply(ioc, pa); 552 mpt_turbo_reply(ioc, pa);
553 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); 553 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
554 } while (pa != 0xFFFFFFFF); 554 } while (pa != 0xFFFFFFFF);
555 555
556 return IRQ_HANDLED; 556 return IRQ_HANDLED;
557 } 557 }
558 558
559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
560 /** 560 /**
561 * mptbase_reply - MPT base driver's callback routine 561 * mptbase_reply - MPT base driver's callback routine
562 * @ioc: Pointer to MPT_ADAPTER structure 562 * @ioc: Pointer to MPT_ADAPTER structure
563 * @req: Pointer to original MPT request frame 563 * @req: Pointer to original MPT request frame
564 * @reply: Pointer to MPT reply frame (NULL if TurboReply) 564 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
565 * 565 *
566 * MPT base driver's callback routine; all base driver 566 * MPT base driver's callback routine; all base driver
567 * "internal" request/reply processing is routed here. 567 * "internal" request/reply processing is routed here.
568 * Currently used for EventNotification and EventAck handling. 568 * Currently used for EventNotification and EventAck handling.
569 * 569 *
570 * Returns 1 indicating original alloc'd request frame ptr 570 * Returns 1 indicating original alloc'd request frame ptr
571 * should be freed, or 0 if it shouldn't. 571 * should be freed, or 0 if it shouldn't.
572 */ 572 */
573 static int 573 static int
574 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) 574 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
575 { 575 {
576 EventNotificationReply_t *pEventReply; 576 EventNotificationReply_t *pEventReply;
577 u8 event; 577 u8 event;
578 int evHandlers; 578 int evHandlers;
579 int freereq = 1; 579 int freereq = 1;
580 580
581 switch (reply->u.hdr.Function) { 581 switch (reply->u.hdr.Function) {
582 case MPI_FUNCTION_EVENT_NOTIFICATION: 582 case MPI_FUNCTION_EVENT_NOTIFICATION:
583 pEventReply = (EventNotificationReply_t *)reply; 583 pEventReply = (EventNotificationReply_t *)reply;
584 evHandlers = 0; 584 evHandlers = 0;
585 ProcessEventNotification(ioc, pEventReply, &evHandlers); 585 ProcessEventNotification(ioc, pEventReply, &evHandlers);
586 event = le32_to_cpu(pEventReply->Event) & 0xFF; 586 event = le32_to_cpu(pEventReply->Event) & 0xFF;
587 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) 587 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
588 freereq = 0; 588 freereq = 0;
589 if (event != MPI_EVENT_EVENT_CHANGE) 589 if (event != MPI_EVENT_EVENT_CHANGE)
590 break; 590 break;
591 case MPI_FUNCTION_CONFIG: 591 case MPI_FUNCTION_CONFIG:
592 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: 592 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
593 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD; 593 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
594 if (reply) { 594 if (reply) {
595 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID; 595 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
596 memcpy(ioc->mptbase_cmds.reply, reply, 596 memcpy(ioc->mptbase_cmds.reply, reply,
597 min(MPT_DEFAULT_FRAME_SIZE, 597 min(MPT_DEFAULT_FRAME_SIZE,
598 4 * reply->u.reply.MsgLength)); 598 4 * reply->u.reply.MsgLength));
599 } 599 }
600 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) { 600 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
601 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING; 601 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
602 complete(&ioc->mptbase_cmds.done); 602 complete(&ioc->mptbase_cmds.done);
603 } else 603 } else
604 freereq = 0; 604 freereq = 0;
605 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF) 605 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
606 freereq = 1; 606 freereq = 1;
607 break; 607 break;
608 case MPI_FUNCTION_EVENT_ACK: 608 case MPI_FUNCTION_EVENT_ACK:
609 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 609 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
610 "EventAck reply received\n", ioc->name)); 610 "EventAck reply received\n", ioc->name));
611 break; 611 break;
612 default: 612 default:
613 printk(MYIOC_s_ERR_FMT 613 printk(MYIOC_s_ERR_FMT
614 "Unexpected msg function (=%02Xh) reply received!\n", 614 "Unexpected msg function (=%02Xh) reply received!\n",
615 ioc->name, reply->u.hdr.Function); 615 ioc->name, reply->u.hdr.Function);
616 break; 616 break;
617 } 617 }
618 618
619 /* 619 /*
620 * Conditionally tell caller to free the original 620 * Conditionally tell caller to free the original
621 * EventNotification/EventAck/unexpected request frame! 621 * EventNotification/EventAck/unexpected request frame!
622 */ 622 */
623 return freereq; 623 return freereq;
624 } 624 }
625 625
626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
627 /** 627 /**
628 * mpt_register - Register protocol-specific main callback handler. 628 * mpt_register - Register protocol-specific main callback handler.
629 * @cbfunc: callback function pointer 629 * @cbfunc: callback function pointer
630 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value) 630 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
631 * 631 *
632 * This routine is called by a protocol-specific driver (SCSI host, 632 * This routine is called by a protocol-specific driver (SCSI host,
633 * LAN, SCSI target) to register its reply callback routine. Each 633 * LAN, SCSI target) to register its reply callback routine. Each
634 * protocol-specific driver must do this before it will be able to 634 * protocol-specific driver must do this before it will be able to
635 * use any IOC resources, such as obtaining request frames. 635 * use any IOC resources, such as obtaining request frames.
636 * 636 *
637 * NOTES: The SCSI protocol driver currently calls this routine thrice 637 * NOTES: The SCSI protocol driver currently calls this routine thrice
638 * in order to register separate callbacks; one for "normal" SCSI IO; 638 * in order to register separate callbacks; one for "normal" SCSI IO;
639 * one for MptScsiTaskMgmt requests; one for Scan/DV requests. 639 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
640 * 640 *
641 * Returns u8 valued "handle" in the range (and S.O.D. order) 641 * Returns u8 valued "handle" in the range (and S.O.D. order)
642 * {N,...,7,6,5,...,1} if successful. 642 * {N,...,7,6,5,...,1} if successful.
643 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be 643 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
644 * considered an error by the caller. 644 * considered an error by the caller.
645 */ 645 */
646 u8 646 u8
647 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) 647 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
648 { 648 {
649 u8 cb_idx; 649 u8 cb_idx;
650 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS; 650 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
651 651
652 /* 652 /*
653 * Search for empty callback slot in this order: {N,...,7,6,5,...,1} 653 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
654 * (slot/handle 0 is reserved!) 654 * (slot/handle 0 is reserved!)
655 */ 655 */
656 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 656 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
657 if (MptCallbacks[cb_idx] == NULL) { 657 if (MptCallbacks[cb_idx] == NULL) {
658 MptCallbacks[cb_idx] = cbfunc; 658 MptCallbacks[cb_idx] = cbfunc;
659 MptDriverClass[cb_idx] = dclass; 659 MptDriverClass[cb_idx] = dclass;
660 MptEvHandlers[cb_idx] = NULL; 660 MptEvHandlers[cb_idx] = NULL;
661 last_drv_idx = cb_idx; 661 last_drv_idx = cb_idx;
662 break; 662 break;
663 } 663 }
664 } 664 }
665 665
666 return last_drv_idx; 666 return last_drv_idx;
667 } 667 }
668 668
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
670 /** 670 /**
671 * mpt_deregister - Deregister a protocol drivers resources. 671 * mpt_deregister - Deregister a protocol drivers resources.
672 * @cb_idx: previously registered callback handle 672 * @cb_idx: previously registered callback handle
673 * 673 *
674 * Each protocol-specific driver should call this routine when its 674 * Each protocol-specific driver should call this routine when its
675 * module is unloaded. 675 * module is unloaded.
676 */ 676 */
677 void 677 void
678 mpt_deregister(u8 cb_idx) 678 mpt_deregister(u8 cb_idx)
679 { 679 {
680 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { 680 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
681 MptCallbacks[cb_idx] = NULL; 681 MptCallbacks[cb_idx] = NULL;
682 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; 682 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
683 MptEvHandlers[cb_idx] = NULL; 683 MptEvHandlers[cb_idx] = NULL;
684 684
685 last_drv_idx++; 685 last_drv_idx++;
686 } 686 }
687 } 687 }
688 688
689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
690 /** 690 /**
691 * mpt_event_register - Register protocol-specific event callback handler. 691 * mpt_event_register - Register protocol-specific event callback handler.
692 * @cb_idx: previously registered (via mpt_register) callback handle 692 * @cb_idx: previously registered (via mpt_register) callback handle
693 * @ev_cbfunc: callback function 693 * @ev_cbfunc: callback function
694 * 694 *
695 * This routine can be called by one or more protocol-specific drivers 695 * This routine can be called by one or more protocol-specific drivers
696 * if/when they choose to be notified of MPT events. 696 * if/when they choose to be notified of MPT events.
697 * 697 *
698 * Returns 0 for success. 698 * Returns 0 for success.
699 */ 699 */
700 int 700 int
701 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc) 701 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
702 { 702 {
703 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 703 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
704 return -1; 704 return -1;
705 705
706 MptEvHandlers[cb_idx] = ev_cbfunc; 706 MptEvHandlers[cb_idx] = ev_cbfunc;
707 return 0; 707 return 0;
708 } 708 }
709 709
710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
711 /** 711 /**
712 * mpt_event_deregister - Deregister protocol-specific event callback handler 712 * mpt_event_deregister - Deregister protocol-specific event callback handler
713 * @cb_idx: previously registered callback handle 713 * @cb_idx: previously registered callback handle
714 * 714 *
715 * Each protocol-specific driver should call this routine 715 * Each protocol-specific driver should call this routine
716 * when it does not (or can no longer) handle events, 716 * when it does not (or can no longer) handle events,
717 * or when its module is unloaded. 717 * or when its module is unloaded.
718 */ 718 */
719 void 719 void
720 mpt_event_deregister(u8 cb_idx) 720 mpt_event_deregister(u8 cb_idx)
721 { 721 {
722 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 722 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
723 return; 723 return;
724 724
725 MptEvHandlers[cb_idx] = NULL; 725 MptEvHandlers[cb_idx] = NULL;
726 } 726 }
727 727
728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
729 /** 729 /**
730 * mpt_reset_register - Register protocol-specific IOC reset handler. 730 * mpt_reset_register - Register protocol-specific IOC reset handler.
731 * @cb_idx: previously registered (via mpt_register) callback handle 731 * @cb_idx: previously registered (via mpt_register) callback handle
732 * @reset_func: reset function 732 * @reset_func: reset function
733 * 733 *
734 * This routine can be called by one or more protocol-specific drivers 734 * This routine can be called by one or more protocol-specific drivers
735 * if/when they choose to be notified of IOC resets. 735 * if/when they choose to be notified of IOC resets.
736 * 736 *
737 * Returns 0 for success. 737 * Returns 0 for success.
738 */ 738 */
739 int 739 int
740 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func) 740 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
741 { 741 {
742 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 742 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
743 return -1; 743 return -1;
744 744
745 MptResetHandlers[cb_idx] = reset_func; 745 MptResetHandlers[cb_idx] = reset_func;
746 return 0; 746 return 0;
747 } 747 }
748 748
749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
750 /** 750 /**
751 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler. 751 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
752 * @cb_idx: previously registered callback handle 752 * @cb_idx: previously registered callback handle
753 * 753 *
754 * Each protocol-specific driver should call this routine 754 * Each protocol-specific driver should call this routine
755 * when it does not (or can no longer) handle IOC reset handling, 755 * when it does not (or can no longer) handle IOC reset handling,
756 * or when its module is unloaded. 756 * or when its module is unloaded.
757 */ 757 */
758 void 758 void
759 mpt_reset_deregister(u8 cb_idx) 759 mpt_reset_deregister(u8 cb_idx)
760 { 760 {
761 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 761 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
762 return; 762 return;
763 763
764 MptResetHandlers[cb_idx] = NULL; 764 MptResetHandlers[cb_idx] = NULL;
765 } 765 }
766 766
767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
768 /** 768 /**
769 * mpt_device_driver_register - Register device driver hooks 769 * mpt_device_driver_register - Register device driver hooks
770 * @dd_cbfunc: driver callbacks struct 770 * @dd_cbfunc: driver callbacks struct
771 * @cb_idx: MPT protocol driver index 771 * @cb_idx: MPT protocol driver index
772 */ 772 */
773 int 773 int
774 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx) 774 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
775 { 775 {
776 MPT_ADAPTER *ioc; 776 MPT_ADAPTER *ioc;
777 const struct pci_device_id *id; 777 const struct pci_device_id *id;
778 778
779 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 779 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
780 return -EINVAL; 780 return -EINVAL;
781 781
782 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; 782 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
783 783
784 /* call per pci device probe entry point */ 784 /* call per pci device probe entry point */
785 list_for_each_entry(ioc, &ioc_list, list) { 785 list_for_each_entry(ioc, &ioc_list, list) {
786 id = ioc->pcidev->driver ? 786 id = ioc->pcidev->driver ?
787 ioc->pcidev->driver->id_table : NULL; 787 ioc->pcidev->driver->id_table : NULL;
788 if (dd_cbfunc->probe) 788 if (dd_cbfunc->probe)
789 dd_cbfunc->probe(ioc->pcidev, id); 789 dd_cbfunc->probe(ioc->pcidev, id);
790 } 790 }
791 791
792 return 0; 792 return 0;
793 } 793 }
794 794
795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
796 /** 796 /**
797 * mpt_device_driver_deregister - DeRegister device driver hooks 797 * mpt_device_driver_deregister - DeRegister device driver hooks
798 * @cb_idx: MPT protocol driver index 798 * @cb_idx: MPT protocol driver index
799 */ 799 */
800 void 800 void
801 mpt_device_driver_deregister(u8 cb_idx) 801 mpt_device_driver_deregister(u8 cb_idx)
802 { 802 {
803 struct mpt_pci_driver *dd_cbfunc; 803 struct mpt_pci_driver *dd_cbfunc;
804 MPT_ADAPTER *ioc; 804 MPT_ADAPTER *ioc;
805 805
806 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 806 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
807 return; 807 return;
808 808
809 dd_cbfunc = MptDeviceDriverHandlers[cb_idx]; 809 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
810 810
811 list_for_each_entry(ioc, &ioc_list, list) { 811 list_for_each_entry(ioc, &ioc_list, list) {
812 if (dd_cbfunc->remove) 812 if (dd_cbfunc->remove)
813 dd_cbfunc->remove(ioc->pcidev); 813 dd_cbfunc->remove(ioc->pcidev);
814 } 814 }
815 815
816 MptDeviceDriverHandlers[cb_idx] = NULL; 816 MptDeviceDriverHandlers[cb_idx] = NULL;
817 } 817 }
818 818
819 819
820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
821 /** 821 /**
822 * mpt_get_msg_frame - Obtain an MPT request frame from the pool 822 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
823 * @cb_idx: Handle of registered MPT protocol driver 823 * @cb_idx: Handle of registered MPT protocol driver
824 * @ioc: Pointer to MPT adapter structure 824 * @ioc: Pointer to MPT adapter structure
825 * 825 *
826 * Obtain an MPT request frame from the pool (of 1024) that are 826 * Obtain an MPT request frame from the pool (of 1024) that are
827 * allocated per MPT adapter. 827 * allocated per MPT adapter.
828 * 828 *
829 * Returns pointer to a MPT request frame or %NULL if none are available 829 * Returns pointer to a MPT request frame or %NULL if none are available
830 * or IOC is not active. 830 * or IOC is not active.
831 */ 831 */
832 MPT_FRAME_HDR* 832 MPT_FRAME_HDR*
833 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) 833 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
834 { 834 {
835 MPT_FRAME_HDR *mf; 835 MPT_FRAME_HDR *mf;
836 unsigned long flags; 836 unsigned long flags;
837 u16 req_idx; /* Request index */ 837 u16 req_idx; /* Request index */
838 838
839 /* validate handle and ioc identifier */ 839 /* validate handle and ioc identifier */
840 840
841 #ifdef MFCNT 841 #ifdef MFCNT
842 if (!ioc->active) 842 if (!ioc->active)
843 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame " 843 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
844 "returning NULL!\n", ioc->name); 844 "returning NULL!\n", ioc->name);
845 #endif 845 #endif
846 846
847 /* If interrupts are not attached, do not return a request frame */ 847 /* If interrupts are not attached, do not return a request frame */
848 if (!ioc->active) 848 if (!ioc->active)
849 return NULL; 849 return NULL;
850 850
851 spin_lock_irqsave(&ioc->FreeQlock, flags); 851 spin_lock_irqsave(&ioc->FreeQlock, flags);
852 if (!list_empty(&ioc->FreeQ)) { 852 if (!list_empty(&ioc->FreeQ)) {
853 int req_offset; 853 int req_offset;
854 854
855 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR, 855 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
856 u.frame.linkage.list); 856 u.frame.linkage.list);
857 list_del(&mf->u.frame.linkage.list); 857 list_del(&mf->u.frame.linkage.list);
858 mf->u.frame.linkage.arg1 = 0; 858 mf->u.frame.linkage.arg1 = 0;
859 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */ 859 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
860 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 860 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
861 /* u16! */ 861 /* u16! */
862 req_idx = req_offset / ioc->req_sz; 862 req_idx = req_offset / ioc->req_sz;
863 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 863 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
864 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 864 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
865 /* Default, will be changed if necessary in SG generation */ 865 /* Default, will be changed if necessary in SG generation */
866 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; 866 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
867 #ifdef MFCNT 867 #ifdef MFCNT
868 ioc->mfcnt++; 868 ioc->mfcnt++;
869 #endif 869 #endif
870 } 870 }
871 else 871 else
872 mf = NULL; 872 mf = NULL;
873 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 873 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
874 874
875 #ifdef MFCNT 875 #ifdef MFCNT
876 if (mf == NULL) 876 if (mf == NULL)
877 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! " 877 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
878 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt, 878 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
879 ioc->req_depth); 879 ioc->req_depth);
880 mfcounter++; 880 mfcounter++;
881 if (mfcounter == PRINT_MF_COUNT) 881 if (mfcounter == PRINT_MF_COUNT)
882 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name, 882 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
883 ioc->mfcnt, ioc->req_depth); 883 ioc->mfcnt, ioc->req_depth);
884 #endif 884 #endif
885 885
886 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n", 886 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
887 ioc->name, cb_idx, ioc->id, mf)); 887 ioc->name, cb_idx, ioc->id, mf));
888 return mf; 888 return mf;
889 } 889 }
890 890
891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
892 /** 892 /**
893 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC 893 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
894 * @cb_idx: Handle of registered MPT protocol driver 894 * @cb_idx: Handle of registered MPT protocol driver
895 * @ioc: Pointer to MPT adapter structure 895 * @ioc: Pointer to MPT adapter structure
896 * @mf: Pointer to MPT request frame 896 * @mf: Pointer to MPT request frame
897 * 897 *
898 * This routine posts an MPT request frame to the request post FIFO of a 898 * This routine posts an MPT request frame to the request post FIFO of a
899 * specific MPT adapter. 899 * specific MPT adapter.
900 */ 900 */
901 void 901 void
902 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 902 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
903 { 903 {
904 u32 mf_dma_addr; 904 u32 mf_dma_addr;
905 int req_offset; 905 int req_offset;
906 u16 req_idx; /* Request index */ 906 u16 req_idx; /* Request index */
907 907
908 /* ensure values are reset properly! */ 908 /* ensure values are reset properly! */
909 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */ 909 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
910 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 910 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
911 /* u16! */ 911 /* u16! */
912 req_idx = req_offset / ioc->req_sz; 912 req_idx = req_offset / ioc->req_sz;
913 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 913 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
914 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 914 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
915 915
916 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf); 916 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
917 917
918 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx]; 918 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
919 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d " 919 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
920 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, 920 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
921 ioc->RequestNB[req_idx])); 921 ioc->RequestNB[req_idx]));
922 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr); 922 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
923 } 923 }
924 924
925 /** 925 /**
926 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame 926 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
927 * @cb_idx: Handle of registered MPT protocol driver 927 * @cb_idx: Handle of registered MPT protocol driver
928 * @ioc: Pointer to MPT adapter structure 928 * @ioc: Pointer to MPT adapter structure
929 * @mf: Pointer to MPT request frame 929 * @mf: Pointer to MPT request frame
930 * 930 *
931 * Send a protocol-specific MPT request frame to an IOC using 931 * Send a protocol-specific MPT request frame to an IOC using
932 * hi-priority request queue. 932 * hi-priority request queue.
933 * 933 *
934 * This routine posts an MPT request frame to the request post FIFO of a 934 * This routine posts an MPT request frame to the request post FIFO of a
935 * specific MPT adapter. 935 * specific MPT adapter.
936 **/ 936 **/
937 void 937 void
938 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 938 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
939 { 939 {
940 u32 mf_dma_addr; 940 u32 mf_dma_addr;
941 int req_offset; 941 int req_offset;
942 u16 req_idx; /* Request index */ 942 u16 req_idx; /* Request index */
943 943
944 /* ensure values are reset properly! */ 944 /* ensure values are reset properly! */
945 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; 945 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
946 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 946 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
947 req_idx = req_offset / ioc->req_sz; 947 req_idx = req_offset / ioc->req_sz;
948 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 948 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
949 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 949 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
950 950
951 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf); 951 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
952 952
953 mf_dma_addr = (ioc->req_frames_low_dma + req_offset); 953 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
954 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n", 954 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
955 ioc->name, mf_dma_addr, req_idx)); 955 ioc->name, mf_dma_addr, req_idx));
956 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr); 956 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
957 } 957 }
958 958
959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
960 /** 960 /**
961 * mpt_free_msg_frame - Place MPT request frame back on FreeQ. 961 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
962 * @ioc: Pointer to MPT adapter structure 962 * @ioc: Pointer to MPT adapter structure
963 * @mf: Pointer to MPT request frame 963 * @mf: Pointer to MPT request frame
964 * 964 *
965 * This routine places a MPT request frame back on the MPT adapter's 965 * This routine places a MPT request frame back on the MPT adapter's
966 * FreeQ. 966 * FreeQ.
967 */ 967 */
968 void 968 void
969 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 969 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
970 { 970 {
971 unsigned long flags; 971 unsigned long flags;
972 972
973 /* Put Request back on FreeQ! */ 973 /* Put Request back on FreeQ! */
974 spin_lock_irqsave(&ioc->FreeQlock, flags); 974 spin_lock_irqsave(&ioc->FreeQlock, flags);
975 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf) 975 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
976 goto out; 976 goto out;
977 /* signature to know if this mf is freed */ 977 /* signature to know if this mf is freed */
978 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf); 978 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
979 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 979 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
980 #ifdef MFCNT 980 #ifdef MFCNT
981 ioc->mfcnt--; 981 ioc->mfcnt--;
982 #endif 982 #endif
983 out: 983 out:
984 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 984 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
985 } 985 }
986 986
987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
988 /** 988 /**
989 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr. 989 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
990 * @pAddr: virtual address for SGE 990 * @pAddr: virtual address for SGE
991 * @flagslength: SGE flags and data transfer length 991 * @flagslength: SGE flags and data transfer length
992 * @dma_addr: Physical address 992 * @dma_addr: Physical address
993 * 993 *
994 * This routine places a MPT request frame back on the MPT adapter's 994 * This routine places a MPT request frame back on the MPT adapter's
995 * FreeQ. 995 * FreeQ.
996 */ 996 */
997 static void 997 static void
998 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr) 998 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
999 { 999 {
1000 SGESimple32_t *pSge = (SGESimple32_t *) pAddr; 1000 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1001 pSge->FlagsLength = cpu_to_le32(flagslength); 1001 pSge->FlagsLength = cpu_to_le32(flagslength);
1002 pSge->Address = cpu_to_le32(dma_addr); 1002 pSge->Address = cpu_to_le32(dma_addr);
1003 } 1003 }
1004 1004
1005 /** 1005 /**
1006 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr. 1006 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1007 * @pAddr: virtual address for SGE 1007 * @pAddr: virtual address for SGE
1008 * @flagslength: SGE flags and data transfer length 1008 * @flagslength: SGE flags and data transfer length
1009 * @dma_addr: Physical address 1009 * @dma_addr: Physical address
1010 * 1010 *
1011 * This routine places a MPT request frame back on the MPT adapter's 1011 * This routine places a MPT request frame back on the MPT adapter's
1012 * FreeQ. 1012 * FreeQ.
1013 **/ 1013 **/
1014 static void 1014 static void
1015 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr) 1015 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1016 { 1016 {
1017 SGESimple64_t *pSge = (SGESimple64_t *) pAddr; 1017 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1018 pSge->Address.Low = cpu_to_le32 1018 pSge->Address.Low = cpu_to_le32
1019 (lower_32_bits(dma_addr)); 1019 (lower_32_bits(dma_addr));
1020 pSge->Address.High = cpu_to_le32 1020 pSge->Address.High = cpu_to_le32
1021 (upper_32_bits(dma_addr)); 1021 (upper_32_bits(dma_addr));
1022 pSge->FlagsLength = cpu_to_le32 1022 pSge->FlagsLength = cpu_to_le32
1023 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING)); 1023 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1024 } 1024 }
1025 1025
1026 /** 1026 /**
1027 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround). 1027 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1028 * @pAddr: virtual address for SGE 1028 * @pAddr: virtual address for SGE
1029 * @flagslength: SGE flags and data transfer length 1029 * @flagslength: SGE flags and data transfer length
1030 * @dma_addr: Physical address 1030 * @dma_addr: Physical address
1031 * 1031 *
1032 * This routine places a MPT request frame back on the MPT adapter's 1032 * This routine places a MPT request frame back on the MPT adapter's
1033 * FreeQ. 1033 * FreeQ.
1034 **/ 1034 **/
1035 static void 1035 static void
1036 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr) 1036 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1037 { 1037 {
1038 SGESimple64_t *pSge = (SGESimple64_t *) pAddr; 1038 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1039 u32 tmp; 1039 u32 tmp;
1040 1040
1041 pSge->Address.Low = cpu_to_le32 1041 pSge->Address.Low = cpu_to_le32
1042 (lower_32_bits(dma_addr)); 1042 (lower_32_bits(dma_addr));
1043 tmp = (u32)(upper_32_bits(dma_addr)); 1043 tmp = (u32)(upper_32_bits(dma_addr));
1044 1044
1045 /* 1045 /*
1046 * 1078 errata workaround for the 36GB limitation 1046 * 1078 errata workaround for the 36GB limitation
1047 */ 1047 */
1048 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) { 1048 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1049 flagslength |= 1049 flagslength |=
1050 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS); 1050 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1051 tmp |= (1<<31); 1051 tmp |= (1<<31);
1052 if (mpt_debug_level & MPT_DEBUG_36GB_MEM) 1052 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1053 printk(KERN_DEBUG "1078 P0M2 addressing for " 1053 printk(KERN_DEBUG "1078 P0M2 addressing for "
1054 "addr = 0x%llx len = %d\n", 1054 "addr = 0x%llx len = %d\n",
1055 (unsigned long long)dma_addr, 1055 (unsigned long long)dma_addr,
1056 MPI_SGE_LENGTH(flagslength)); 1056 MPI_SGE_LENGTH(flagslength));
1057 } 1057 }
1058 1058
1059 pSge->Address.High = cpu_to_le32(tmp); 1059 pSge->Address.High = cpu_to_le32(tmp);
1060 pSge->FlagsLength = cpu_to_le32( 1060 pSge->FlagsLength = cpu_to_le32(
1061 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING)); 1061 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1062 } 1062 }
1063 1063
1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1065 /** 1065 /**
1066 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr. 1066 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1067 * @pAddr: virtual address for SGE 1067 * @pAddr: virtual address for SGE
1068 * @next: nextChainOffset value (u32's) 1068 * @next: nextChainOffset value (u32's)
1069 * @length: length of next SGL segment 1069 * @length: length of next SGL segment
1070 * @dma_addr: Physical address 1070 * @dma_addr: Physical address
1071 * 1071 *
1072 */ 1072 */
1073 static void 1073 static void
1074 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr) 1074 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1075 { 1075 {
1076 SGEChain32_t *pChain = (SGEChain32_t *) pAddr; 1076 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1077 pChain->Length = cpu_to_le16(length); 1077 pChain->Length = cpu_to_le16(length);
1078 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT; 1078 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1079 pChain->NextChainOffset = next; 1079 pChain->NextChainOffset = next;
1080 pChain->Address = cpu_to_le32(dma_addr); 1080 pChain->Address = cpu_to_le32(dma_addr);
1081 } 1081 }
1082 1082
1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1084 /** 1084 /**
1085 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr. 1085 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1086 * @pAddr: virtual address for SGE 1086 * @pAddr: virtual address for SGE
1087 * @next: nextChainOffset value (u32's) 1087 * @next: nextChainOffset value (u32's)
1088 * @length: length of next SGL segment 1088 * @length: length of next SGL segment
1089 * @dma_addr: Physical address 1089 * @dma_addr: Physical address
1090 * 1090 *
1091 */ 1091 */
1092 static void 1092 static void
1093 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr) 1093 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1094 { 1094 {
1095 SGEChain64_t *pChain = (SGEChain64_t *) pAddr; 1095 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1096 u32 tmp = dma_addr & 0xFFFFFFFF; 1096 u32 tmp = dma_addr & 0xFFFFFFFF;
1097 1097
1098 pChain->Length = cpu_to_le16(length); 1098 pChain->Length = cpu_to_le16(length);
1099 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT | 1099 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1100 MPI_SGE_FLAGS_64_BIT_ADDRESSING); 1100 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1101 1101
1102 pChain->NextChainOffset = next; 1102 pChain->NextChainOffset = next;
1103 1103
1104 pChain->Address.Low = cpu_to_le32(tmp); 1104 pChain->Address.Low = cpu_to_le32(tmp);
1105 tmp = (u32)(upper_32_bits(dma_addr)); 1105 tmp = (u32)(upper_32_bits(dma_addr));
1106 pChain->Address.High = cpu_to_le32(tmp); 1106 pChain->Address.High = cpu_to_le32(tmp);
1107 } 1107 }
1108 1108
1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1110 /** 1110 /**
1111 * mpt_send_handshake_request - Send MPT request via doorbell handshake method. 1111 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1112 * @cb_idx: Handle of registered MPT protocol driver 1112 * @cb_idx: Handle of registered MPT protocol driver
1113 * @ioc: Pointer to MPT adapter structure 1113 * @ioc: Pointer to MPT adapter structure
1114 * @reqBytes: Size of the request in bytes 1114 * @reqBytes: Size of the request in bytes
1115 * @req: Pointer to MPT request frame 1115 * @req: Pointer to MPT request frame
1116 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. 1116 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1117 * 1117 *
1118 * This routine is used exclusively to send MptScsiTaskMgmt 1118 * This routine is used exclusively to send MptScsiTaskMgmt
1119 * requests since they are required to be sent via doorbell handshake. 1119 * requests since they are required to be sent via doorbell handshake.
1120 * 1120 *
1121 * NOTE: It is the callers responsibility to byte-swap fields in the 1121 * NOTE: It is the callers responsibility to byte-swap fields in the
1122 * request which are greater than 1 byte in size. 1122 * request which are greater than 1 byte in size.
1123 * 1123 *
1124 * Returns 0 for success, non-zero for failure. 1124 * Returns 0 for success, non-zero for failure.
1125 */ 1125 */
1126 int 1126 int
1127 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) 1127 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1128 { 1128 {
1129 int r = 0; 1129 int r = 0;
1130 u8 *req_as_bytes; 1130 u8 *req_as_bytes;
1131 int ii; 1131 int ii;
1132 1132
1133 /* State is known to be good upon entering 1133 /* State is known to be good upon entering
1134 * this function so issue the bus reset 1134 * this function so issue the bus reset
1135 * request. 1135 * request.
1136 */ 1136 */
1137 1137
1138 /* 1138 /*
1139 * Emulate what mpt_put_msg_frame() does /wrt to sanity 1139 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1140 * setting cb_idx/req_idx. But ONLY if this request 1140 * setting cb_idx/req_idx. But ONLY if this request
1141 * is in proper (pre-alloc'd) request buffer range... 1141 * is in proper (pre-alloc'd) request buffer range...
1142 */ 1142 */
1143 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req); 1143 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1144 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) { 1144 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1145 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req; 1145 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1146 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii); 1146 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1147 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; 1147 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1148 } 1148 }
1149 1149
1150 /* Make sure there are no doorbells */ 1150 /* Make sure there are no doorbells */
1151 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1151 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1152 1152
1153 CHIPREG_WRITE32(&ioc->chip->Doorbell, 1153 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1154 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) | 1154 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1155 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))); 1155 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1156 1156
1157 /* Wait for IOC doorbell int */ 1157 /* Wait for IOC doorbell int */
1158 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) { 1158 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1159 return ii; 1159 return ii;
1160 } 1160 }
1161 1161
1162 /* Read doorbell and check for active bit */ 1162 /* Read doorbell and check for active bit */
1163 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE)) 1163 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1164 return -5; 1164 return -5;
1165 1165
1166 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n", 1166 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1167 ioc->name, ii)); 1167 ioc->name, ii));
1168 1168
1169 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1169 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1170 1170
1171 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1171 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1172 return -2; 1172 return -2;
1173 } 1173 }
1174 1174
1175 /* Send request via doorbell handshake */ 1175 /* Send request via doorbell handshake */
1176 req_as_bytes = (u8 *) req; 1176 req_as_bytes = (u8 *) req;
1177 for (ii = 0; ii < reqBytes/4; ii++) { 1177 for (ii = 0; ii < reqBytes/4; ii++) {
1178 u32 word; 1178 u32 word;
1179 1179
1180 word = ((req_as_bytes[(ii*4) + 0] << 0) | 1180 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1181 (req_as_bytes[(ii*4) + 1] << 8) | 1181 (req_as_bytes[(ii*4) + 1] << 8) |
1182 (req_as_bytes[(ii*4) + 2] << 16) | 1182 (req_as_bytes[(ii*4) + 2] << 16) |
1183 (req_as_bytes[(ii*4) + 3] << 24)); 1183 (req_as_bytes[(ii*4) + 3] << 24));
1184 CHIPREG_WRITE32(&ioc->chip->Doorbell, word); 1184 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1185 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1185 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1186 r = -3; 1186 r = -3;
1187 break; 1187 break;
1188 } 1188 }
1189 } 1189 }
1190 1190
1191 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0) 1191 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1192 r = 0; 1192 r = 0;
1193 else 1193 else
1194 r = -4; 1194 r = -4;
1195 1195
1196 /* Make sure there are no doorbells */ 1196 /* Make sure there are no doorbells */
1197 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1197 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1198 1198
1199 return r; 1199 return r;
1200 } 1200 }
1201 1201
1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1203 /** 1203 /**
1204 * mpt_host_page_access_control - control the IOC's Host Page Buffer access 1204 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1205 * @ioc: Pointer to MPT adapter structure 1205 * @ioc: Pointer to MPT adapter structure
1206 * @access_control_value: define bits below 1206 * @access_control_value: define bits below
1207 * @sleepFlag: Specifies whether the process can sleep 1207 * @sleepFlag: Specifies whether the process can sleep
1208 * 1208 *
1209 * Provides mechanism for the host driver to control the IOC's 1209 * Provides mechanism for the host driver to control the IOC's
1210 * Host Page Buffer access. 1210 * Host Page Buffer access.
1211 * 1211 *
1212 * Access Control Value - bits[15:12] 1212 * Access Control Value - bits[15:12]
1213 * 0h Reserved 1213 * 0h Reserved
1214 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS } 1214 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1215 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS } 1215 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1216 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER } 1216 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1217 * 1217 *
1218 * Returns 0 for success, non-zero for failure. 1218 * Returns 0 for success, non-zero for failure.
1219 */ 1219 */
1220 1220
1221 static int 1221 static int
1222 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag) 1222 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1223 { 1223 {
1224 int r = 0; 1224 int r = 0;
1225 1225
1226 /* return if in use */ 1226 /* return if in use */
1227 if (CHIPREG_READ32(&ioc->chip->Doorbell) 1227 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1228 & MPI_DOORBELL_ACTIVE) 1228 & MPI_DOORBELL_ACTIVE)
1229 return -1; 1229 return -1;
1230 1230
1231 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1231 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1232 1232
1233 CHIPREG_WRITE32(&ioc->chip->Doorbell, 1233 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1234 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL 1234 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1235 <<MPI_DOORBELL_FUNCTION_SHIFT) | 1235 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1236 (access_control_value<<12))); 1236 (access_control_value<<12)));
1237 1237
1238 /* Wait for IOC to clear Doorbell Status bit */ 1238 /* Wait for IOC to clear Doorbell Status bit */
1239 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1239 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1240 return -2; 1240 return -2;
1241 }else 1241 }else
1242 return 0; 1242 return 0;
1243 } 1243 }
1244 1244
1245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1246 /** 1246 /**
1247 * mpt_host_page_alloc - allocate system memory for the fw 1247 * mpt_host_page_alloc - allocate system memory for the fw
1248 * @ioc: Pointer to pointer to IOC adapter 1248 * @ioc: Pointer to pointer to IOC adapter
1249 * @ioc_init: Pointer to ioc init config page 1249 * @ioc_init: Pointer to ioc init config page
1250 * 1250 *
1251 * If we already allocated memory in past, then resend the same pointer. 1251 * If we already allocated memory in past, then resend the same pointer.
1252 * Returns 0 for success, non-zero for failure. 1252 * Returns 0 for success, non-zero for failure.
1253 */ 1253 */
1254 static int 1254 static int
1255 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init) 1255 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1256 { 1256 {
1257 char *psge; 1257 char *psge;
1258 int flags_length; 1258 int flags_length;
1259 u32 host_page_buffer_sz=0; 1259 u32 host_page_buffer_sz=0;
1260 1260
1261 if(!ioc->HostPageBuffer) { 1261 if(!ioc->HostPageBuffer) {
1262 1262
1263 host_page_buffer_sz = 1263 host_page_buffer_sz =
1264 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF; 1264 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1265 1265
1266 if(!host_page_buffer_sz) 1266 if(!host_page_buffer_sz)
1267 return 0; /* fw doesn't need any host buffers */ 1267 return 0; /* fw doesn't need any host buffers */
1268 1268
1269 /* spin till we get enough memory */ 1269 /* spin till we get enough memory */
1270 while(host_page_buffer_sz > 0) { 1270 while(host_page_buffer_sz > 0) {
1271 1271
1272 if((ioc->HostPageBuffer = pci_alloc_consistent( 1272 if((ioc->HostPageBuffer = pci_alloc_consistent(
1273 ioc->pcidev, 1273 ioc->pcidev,
1274 host_page_buffer_sz, 1274 host_page_buffer_sz,
1275 &ioc->HostPageBuffer_dma)) != NULL) { 1275 &ioc->HostPageBuffer_dma)) != NULL) {
1276 1276
1277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 1277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1278 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", 1278 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1279 ioc->name, ioc->HostPageBuffer, 1279 ioc->name, ioc->HostPageBuffer,
1280 (u32)ioc->HostPageBuffer_dma, 1280 (u32)ioc->HostPageBuffer_dma,
1281 host_page_buffer_sz)); 1281 host_page_buffer_sz));
1282 ioc->alloc_total += host_page_buffer_sz; 1282 ioc->alloc_total += host_page_buffer_sz;
1283 ioc->HostPageBuffer_sz = host_page_buffer_sz; 1283 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1284 break; 1284 break;
1285 } 1285 }
1286 1286
1287 host_page_buffer_sz -= (4*1024); 1287 host_page_buffer_sz -= (4*1024);
1288 } 1288 }
1289 } 1289 }
1290 1290
1291 if(!ioc->HostPageBuffer) { 1291 if(!ioc->HostPageBuffer) {
1292 printk(MYIOC_s_ERR_FMT 1292 printk(MYIOC_s_ERR_FMT
1293 "Failed to alloc memory for host_page_buffer!\n", 1293 "Failed to alloc memory for host_page_buffer!\n",
1294 ioc->name); 1294 ioc->name);
1295 return -999; 1295 return -999;
1296 } 1296 }
1297 1297
1298 psge = (char *)&ioc_init->HostPageBufferSGE; 1298 psge = (char *)&ioc_init->HostPageBufferSGE;
1299 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT | 1299 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1300 MPI_SGE_FLAGS_SYSTEM_ADDRESS | 1300 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1301 MPI_SGE_FLAGS_HOST_TO_IOC | 1301 MPI_SGE_FLAGS_HOST_TO_IOC |
1302 MPI_SGE_FLAGS_END_OF_BUFFER; 1302 MPI_SGE_FLAGS_END_OF_BUFFER;
1303 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT; 1303 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1304 flags_length |= ioc->HostPageBuffer_sz; 1304 flags_length |= ioc->HostPageBuffer_sz;
1305 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma); 1305 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1306 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE; 1306 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1307 1307
1308 return 0; 1308 return 0;
1309 } 1309 }
1310 1310
1311 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1311 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1312 /** 1312 /**
1313 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure. 1313 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1314 * @iocid: IOC unique identifier (integer) 1314 * @iocid: IOC unique identifier (integer)
1315 * @iocpp: Pointer to pointer to IOC adapter 1315 * @iocpp: Pointer to pointer to IOC adapter
1316 * 1316 *
1317 * Given a unique IOC identifier, set pointer to the associated MPT 1317 * Given a unique IOC identifier, set pointer to the associated MPT
1318 * adapter structure. 1318 * adapter structure.
1319 * 1319 *
1320 * Returns iocid and sets iocpp if iocid is found. 1320 * Returns iocid and sets iocpp if iocid is found.
1321 * Returns -1 if iocid is not found. 1321 * Returns -1 if iocid is not found.
1322 */ 1322 */
1323 int 1323 int
1324 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) 1324 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1325 { 1325 {
1326 MPT_ADAPTER *ioc; 1326 MPT_ADAPTER *ioc;
1327 1327
1328 list_for_each_entry(ioc,&ioc_list,list) { 1328 list_for_each_entry(ioc,&ioc_list,list) {
1329 if (ioc->id == iocid) { 1329 if (ioc->id == iocid) {
1330 *iocpp =ioc; 1330 *iocpp =ioc;
1331 return iocid; 1331 return iocid;
1332 } 1332 }
1333 } 1333 }
1334 1334
1335 *iocpp = NULL; 1335 *iocpp = NULL;
1336 return -1; 1336 return -1;
1337 } 1337 }
1338 1338
1339 /** 1339 /**
1340 * mpt_get_product_name - returns product string 1340 * mpt_get_product_name - returns product string
1341 * @vendor: pci vendor id 1341 * @vendor: pci vendor id
1342 * @device: pci device id 1342 * @device: pci device id
1343 * @revision: pci revision id 1343 * @revision: pci revision id
1344 * @prod_name: string returned 1344 * @prod_name: string returned
1345 * 1345 *
1346 * Returns product string displayed when driver loads, 1346 * Returns product string displayed when driver loads,
1347 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product 1347 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1348 * 1348 *
1349 **/ 1349 **/
1350 static void 1350 static void
1351 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name) 1351 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1352 { 1352 {
1353 char *product_str = NULL; 1353 char *product_str = NULL;
1354 1354
1355 if (vendor == PCI_VENDOR_ID_BROCADE) { 1355 if (vendor == PCI_VENDOR_ID_BROCADE) {
1356 switch (device) 1356 switch (device)
1357 { 1357 {
1358 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1358 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1359 switch (revision) 1359 switch (revision)
1360 { 1360 {
1361 case 0x00: 1361 case 0x00:
1362 product_str = "BRE040 A0"; 1362 product_str = "BRE040 A0";
1363 break; 1363 break;
1364 case 0x01: 1364 case 0x01:
1365 product_str = "BRE040 A1"; 1365 product_str = "BRE040 A1";
1366 break; 1366 break;
1367 default: 1367 default:
1368 product_str = "BRE040"; 1368 product_str = "BRE040";
1369 break; 1369 break;
1370 } 1370 }
1371 break; 1371 break;
1372 } 1372 }
1373 goto out; 1373 goto out;
1374 } 1374 }
1375 1375
1376 switch (device) 1376 switch (device)
1377 { 1377 {
1378 case MPI_MANUFACTPAGE_DEVICEID_FC909: 1378 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1379 product_str = "LSIFC909 B1"; 1379 product_str = "LSIFC909 B1";
1380 break; 1380 break;
1381 case MPI_MANUFACTPAGE_DEVICEID_FC919: 1381 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1382 product_str = "LSIFC919 B0"; 1382 product_str = "LSIFC919 B0";
1383 break; 1383 break;
1384 case MPI_MANUFACTPAGE_DEVICEID_FC929: 1384 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1385 product_str = "LSIFC929 B0"; 1385 product_str = "LSIFC929 B0";
1386 break; 1386 break;
1387 case MPI_MANUFACTPAGE_DEVICEID_FC919X: 1387 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1388 if (revision < 0x80) 1388 if (revision < 0x80)
1389 product_str = "LSIFC919X A0"; 1389 product_str = "LSIFC919X A0";
1390 else 1390 else
1391 product_str = "LSIFC919XL A1"; 1391 product_str = "LSIFC919XL A1";
1392 break; 1392 break;
1393 case MPI_MANUFACTPAGE_DEVICEID_FC929X: 1393 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1394 if (revision < 0x80) 1394 if (revision < 0x80)
1395 product_str = "LSIFC929X A0"; 1395 product_str = "LSIFC929X A0";
1396 else 1396 else
1397 product_str = "LSIFC929XL A1"; 1397 product_str = "LSIFC929XL A1";
1398 break; 1398 break;
1399 case MPI_MANUFACTPAGE_DEVICEID_FC939X: 1399 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1400 product_str = "LSIFC939X A1"; 1400 product_str = "LSIFC939X A1";
1401 break; 1401 break;
1402 case MPI_MANUFACTPAGE_DEVICEID_FC949X: 1402 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1403 product_str = "LSIFC949X A1"; 1403 product_str = "LSIFC949X A1";
1404 break; 1404 break;
1405 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1405 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1406 switch (revision) 1406 switch (revision)
1407 { 1407 {
1408 case 0x00: 1408 case 0x00:
1409 product_str = "LSIFC949E A0"; 1409 product_str = "LSIFC949E A0";
1410 break; 1410 break;
1411 case 0x01: 1411 case 0x01:
1412 product_str = "LSIFC949E A1"; 1412 product_str = "LSIFC949E A1";
1413 break; 1413 break;
1414 default: 1414 default:
1415 product_str = "LSIFC949E"; 1415 product_str = "LSIFC949E";
1416 break; 1416 break;
1417 } 1417 }
1418 break; 1418 break;
1419 case MPI_MANUFACTPAGE_DEVID_53C1030: 1419 case MPI_MANUFACTPAGE_DEVID_53C1030:
1420 switch (revision) 1420 switch (revision)
1421 { 1421 {
1422 case 0x00: 1422 case 0x00:
1423 product_str = "LSI53C1030 A0"; 1423 product_str = "LSI53C1030 A0";
1424 break; 1424 break;
1425 case 0x01: 1425 case 0x01:
1426 product_str = "LSI53C1030 B0"; 1426 product_str = "LSI53C1030 B0";
1427 break; 1427 break;
1428 case 0x03: 1428 case 0x03:
1429 product_str = "LSI53C1030 B1"; 1429 product_str = "LSI53C1030 B1";
1430 break; 1430 break;
1431 case 0x07: 1431 case 0x07:
1432 product_str = "LSI53C1030 B2"; 1432 product_str = "LSI53C1030 B2";
1433 break; 1433 break;
1434 case 0x08: 1434 case 0x08:
1435 product_str = "LSI53C1030 C0"; 1435 product_str = "LSI53C1030 C0";
1436 break; 1436 break;
1437 case 0x80: 1437 case 0x80:
1438 product_str = "LSI53C1030T A0"; 1438 product_str = "LSI53C1030T A0";
1439 break; 1439 break;
1440 case 0x83: 1440 case 0x83:
1441 product_str = "LSI53C1030T A2"; 1441 product_str = "LSI53C1030T A2";
1442 break; 1442 break;
1443 case 0x87: 1443 case 0x87:
1444 product_str = "LSI53C1030T A3"; 1444 product_str = "LSI53C1030T A3";
1445 break; 1445 break;
1446 case 0xc1: 1446 case 0xc1:
1447 product_str = "LSI53C1020A A1"; 1447 product_str = "LSI53C1020A A1";
1448 break; 1448 break;
1449 default: 1449 default:
1450 product_str = "LSI53C1030"; 1450 product_str = "LSI53C1030";
1451 break; 1451 break;
1452 } 1452 }
1453 break; 1453 break;
1454 case MPI_MANUFACTPAGE_DEVID_1030_53C1035: 1454 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1455 switch (revision) 1455 switch (revision)
1456 { 1456 {
1457 case 0x03: 1457 case 0x03:
1458 product_str = "LSI53C1035 A2"; 1458 product_str = "LSI53C1035 A2";
1459 break; 1459 break;
1460 case 0x04: 1460 case 0x04:
1461 product_str = "LSI53C1035 B0"; 1461 product_str = "LSI53C1035 B0";
1462 break; 1462 break;
1463 default: 1463 default:
1464 product_str = "LSI53C1035"; 1464 product_str = "LSI53C1035";
1465 break; 1465 break;
1466 } 1466 }
1467 break; 1467 break;
1468 case MPI_MANUFACTPAGE_DEVID_SAS1064: 1468 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1469 switch (revision) 1469 switch (revision)
1470 { 1470 {
1471 case 0x00: 1471 case 0x00:
1472 product_str = "LSISAS1064 A1"; 1472 product_str = "LSISAS1064 A1";
1473 break; 1473 break;
1474 case 0x01: 1474 case 0x01:
1475 product_str = "LSISAS1064 A2"; 1475 product_str = "LSISAS1064 A2";
1476 break; 1476 break;
1477 case 0x02: 1477 case 0x02:
1478 product_str = "LSISAS1064 A3"; 1478 product_str = "LSISAS1064 A3";
1479 break; 1479 break;
1480 case 0x03: 1480 case 0x03:
1481 product_str = "LSISAS1064 A4"; 1481 product_str = "LSISAS1064 A4";
1482 break; 1482 break;
1483 default: 1483 default:
1484 product_str = "LSISAS1064"; 1484 product_str = "LSISAS1064";
1485 break; 1485 break;
1486 } 1486 }
1487 break; 1487 break;
1488 case MPI_MANUFACTPAGE_DEVID_SAS1064E: 1488 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1489 switch (revision) 1489 switch (revision)
1490 { 1490 {
1491 case 0x00: 1491 case 0x00:
1492 product_str = "LSISAS1064E A0"; 1492 product_str = "LSISAS1064E A0";
1493 break; 1493 break;
1494 case 0x01: 1494 case 0x01:
1495 product_str = "LSISAS1064E B0"; 1495 product_str = "LSISAS1064E B0";
1496 break; 1496 break;
1497 case 0x02: 1497 case 0x02:
1498 product_str = "LSISAS1064E B1"; 1498 product_str = "LSISAS1064E B1";
1499 break; 1499 break;
1500 case 0x04: 1500 case 0x04:
1501 product_str = "LSISAS1064E B2"; 1501 product_str = "LSISAS1064E B2";
1502 break; 1502 break;
1503 case 0x08: 1503 case 0x08:
1504 product_str = "LSISAS1064E B3"; 1504 product_str = "LSISAS1064E B3";
1505 break; 1505 break;
1506 default: 1506 default:
1507 product_str = "LSISAS1064E"; 1507 product_str = "LSISAS1064E";
1508 break; 1508 break;
1509 } 1509 }
1510 break; 1510 break;
1511 case MPI_MANUFACTPAGE_DEVID_SAS1068: 1511 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1512 switch (revision) 1512 switch (revision)
1513 { 1513 {
1514 case 0x00: 1514 case 0x00:
1515 product_str = "LSISAS1068 A0"; 1515 product_str = "LSISAS1068 A0";
1516 break; 1516 break;
1517 case 0x01: 1517 case 0x01:
1518 product_str = "LSISAS1068 B0"; 1518 product_str = "LSISAS1068 B0";
1519 break; 1519 break;
1520 case 0x02: 1520 case 0x02:
1521 product_str = "LSISAS1068 B1"; 1521 product_str = "LSISAS1068 B1";
1522 break; 1522 break;
1523 default: 1523 default:
1524 product_str = "LSISAS1068"; 1524 product_str = "LSISAS1068";
1525 break; 1525 break;
1526 } 1526 }
1527 break; 1527 break;
1528 case MPI_MANUFACTPAGE_DEVID_SAS1068E: 1528 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1529 switch (revision) 1529 switch (revision)
1530 { 1530 {
1531 case 0x00: 1531 case 0x00:
1532 product_str = "LSISAS1068E A0"; 1532 product_str = "LSISAS1068E A0";
1533 break; 1533 break;
1534 case 0x01: 1534 case 0x01:
1535 product_str = "LSISAS1068E B0"; 1535 product_str = "LSISAS1068E B0";
1536 break; 1536 break;
1537 case 0x02: 1537 case 0x02:
1538 product_str = "LSISAS1068E B1"; 1538 product_str = "LSISAS1068E B1";
1539 break; 1539 break;
1540 case 0x04: 1540 case 0x04:
1541 product_str = "LSISAS1068E B2"; 1541 product_str = "LSISAS1068E B2";
1542 break; 1542 break;
1543 case 0x08: 1543 case 0x08:
1544 product_str = "LSISAS1068E B3"; 1544 product_str = "LSISAS1068E B3";
1545 break; 1545 break;
1546 default: 1546 default:
1547 product_str = "LSISAS1068E"; 1547 product_str = "LSISAS1068E";
1548 break; 1548 break;
1549 } 1549 }
1550 break; 1550 break;
1551 case MPI_MANUFACTPAGE_DEVID_SAS1078: 1551 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1552 switch (revision) 1552 switch (revision)
1553 { 1553 {
1554 case 0x00: 1554 case 0x00:
1555 product_str = "LSISAS1078 A0"; 1555 product_str = "LSISAS1078 A0";
1556 break; 1556 break;
1557 case 0x01: 1557 case 0x01:
1558 product_str = "LSISAS1078 B0"; 1558 product_str = "LSISAS1078 B0";
1559 break; 1559 break;
1560 case 0x02: 1560 case 0x02:
1561 product_str = "LSISAS1078 C0"; 1561 product_str = "LSISAS1078 C0";
1562 break; 1562 break;
1563 case 0x03: 1563 case 0x03:
1564 product_str = "LSISAS1078 C1"; 1564 product_str = "LSISAS1078 C1";
1565 break; 1565 break;
1566 case 0x04: 1566 case 0x04:
1567 product_str = "LSISAS1078 C2"; 1567 product_str = "LSISAS1078 C2";
1568 break; 1568 break;
1569 default: 1569 default:
1570 product_str = "LSISAS1078"; 1570 product_str = "LSISAS1078";
1571 break; 1571 break;
1572 } 1572 }
1573 break; 1573 break;
1574 } 1574 }
1575 1575
1576 out: 1576 out:
1577 if (product_str) 1577 if (product_str)
1578 sprintf(prod_name, "%s", product_str); 1578 sprintf(prod_name, "%s", product_str);
1579 } 1579 }
1580 1580
1581 /** 1581 /**
1582 * mpt_mapresources - map in memory mapped io 1582 * mpt_mapresources - map in memory mapped io
1583 * @ioc: Pointer to pointer to IOC adapter 1583 * @ioc: Pointer to pointer to IOC adapter
1584 * 1584 *
1585 **/ 1585 **/
1586 static int 1586 static int
1587 mpt_mapresources(MPT_ADAPTER *ioc) 1587 mpt_mapresources(MPT_ADAPTER *ioc)
1588 { 1588 {
1589 u8 __iomem *mem; 1589 u8 __iomem *mem;
1590 int ii; 1590 int ii;
1591 resource_size_t mem_phys; 1591 resource_size_t mem_phys;
1592 unsigned long port; 1592 unsigned long port;
1593 u32 msize; 1593 u32 msize;
1594 u32 psize; 1594 u32 psize;
1595 u8 revision; 1595 u8 revision;
1596 int r = -ENODEV; 1596 int r = -ENODEV;
1597 struct pci_dev *pdev; 1597 struct pci_dev *pdev;
1598 1598
1599 pdev = ioc->pcidev; 1599 pdev = ioc->pcidev;
1600 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); 1600 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1601 if (pci_enable_device_mem(pdev)) { 1601 if (pci_enable_device_mem(pdev)) {
1602 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() " 1602 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1603 "failed\n", ioc->name); 1603 "failed\n", ioc->name);
1604 return r; 1604 return r;
1605 } 1605 }
1606 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) { 1606 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1607 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with " 1607 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1608 "MEM failed\n", ioc->name); 1608 "MEM failed\n", ioc->name);
1609 return r; 1609 return r;
1610 } 1610 }
1611 1611
1612 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 1612 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1613 1613
1614 if (sizeof(dma_addr_t) > 4) { 1614 if (sizeof(dma_addr_t) > 4) {
1615 const uint64_t required_mask = dma_get_required_mask 1615 const uint64_t required_mask = dma_get_required_mask
1616 (&pdev->dev); 1616 (&pdev->dev);
1617 if (required_mask > DMA_BIT_MASK(32) 1617 if (required_mask > DMA_BIT_MASK(32)
1618 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) 1618 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1619 && !pci_set_consistent_dma_mask(pdev, 1619 && !pci_set_consistent_dma_mask(pdev,
1620 DMA_BIT_MASK(64))) { 1620 DMA_BIT_MASK(64))) {
1621 ioc->dma_mask = DMA_BIT_MASK(64); 1621 ioc->dma_mask = DMA_BIT_MASK(64);
1622 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1622 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1623 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1623 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1624 ioc->name)); 1624 ioc->name));
1625 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) 1625 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1626 && !pci_set_consistent_dma_mask(pdev, 1626 && !pci_set_consistent_dma_mask(pdev,
1627 DMA_BIT_MASK(32))) { 1627 DMA_BIT_MASK(32))) {
1628 ioc->dma_mask = DMA_BIT_MASK(32); 1628 ioc->dma_mask = DMA_BIT_MASK(32);
1629 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1629 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1630 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1630 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1631 ioc->name)); 1631 ioc->name));
1632 } else { 1632 } else {
1633 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", 1633 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1634 ioc->name, pci_name(pdev)); 1634 ioc->name, pci_name(pdev));
1635 return r; 1635 return r;
1636 } 1636 }
1637 } else { 1637 } else {
1638 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) 1638 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1639 && !pci_set_consistent_dma_mask(pdev, 1639 && !pci_set_consistent_dma_mask(pdev,
1640 DMA_BIT_MASK(32))) { 1640 DMA_BIT_MASK(32))) {
1641 ioc->dma_mask = DMA_BIT_MASK(32); 1641 ioc->dma_mask = DMA_BIT_MASK(32);
1642 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1642 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1643 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1643 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1644 ioc->name)); 1644 ioc->name));
1645 } else { 1645 } else {
1646 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", 1646 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1647 ioc->name, pci_name(pdev)); 1647 ioc->name, pci_name(pdev));
1648 return r; 1648 return r;
1649 } 1649 }
1650 } 1650 }
1651 1651
1652 mem_phys = msize = 0; 1652 mem_phys = msize = 0;
1653 port = psize = 0; 1653 port = psize = 0;
1654 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) { 1654 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1655 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { 1655 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1656 if (psize) 1656 if (psize)
1657 continue; 1657 continue;
1658 /* Get I/O space! */ 1658 /* Get I/O space! */
1659 port = pci_resource_start(pdev, ii); 1659 port = pci_resource_start(pdev, ii);
1660 psize = pci_resource_len(pdev, ii); 1660 psize = pci_resource_len(pdev, ii);
1661 } else { 1661 } else {
1662 if (msize) 1662 if (msize)
1663 continue; 1663 continue;
1664 /* Get memmap */ 1664 /* Get memmap */
1665 mem_phys = pci_resource_start(pdev, ii); 1665 mem_phys = pci_resource_start(pdev, ii);
1666 msize = pci_resource_len(pdev, ii); 1666 msize = pci_resource_len(pdev, ii);
1667 } 1667 }
1668 } 1668 }
1669 ioc->mem_size = msize; 1669 ioc->mem_size = msize;
1670 1670
1671 mem = NULL; 1671 mem = NULL;
1672 /* Get logical ptr for PciMem0 space */ 1672 /* Get logical ptr for PciMem0 space */
1673 /*mem = ioremap(mem_phys, msize);*/ 1673 /*mem = ioremap(mem_phys, msize);*/
1674 mem = ioremap(mem_phys, msize); 1674 mem = ioremap(mem_phys, msize);
1675 if (mem == NULL) { 1675 if (mem == NULL) {
1676 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter" 1676 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1677 " memory!\n", ioc->name); 1677 " memory!\n", ioc->name);
1678 return -EINVAL; 1678 return -EINVAL;
1679 } 1679 }
1680 ioc->memmap = mem; 1680 ioc->memmap = mem;
1681 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n", 1681 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1682 ioc->name, mem, (unsigned long long)mem_phys)); 1682 ioc->name, mem, (unsigned long long)mem_phys));
1683 1683
1684 ioc->mem_phys = mem_phys; 1684 ioc->mem_phys = mem_phys;
1685 ioc->chip = (SYSIF_REGS __iomem *)mem; 1685 ioc->chip = (SYSIF_REGS __iomem *)mem;
1686 1686
1687 /* Save Port IO values in case we need to do downloadboot */ 1687 /* Save Port IO values in case we need to do downloadboot */
1688 ioc->pio_mem_phys = port; 1688 ioc->pio_mem_phys = port;
1689 ioc->pio_chip = (SYSIF_REGS __iomem *)port; 1689 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1690 1690
1691 return 0; 1691 return 0;
1692 } 1692 }
1693 1693
1694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1695 /** 1695 /**
1696 * mpt_attach - Install a PCI intelligent MPT adapter. 1696 * mpt_attach - Install a PCI intelligent MPT adapter.
1697 * @pdev: Pointer to pci_dev structure 1697 * @pdev: Pointer to pci_dev structure
1698 * @id: PCI device ID information 1698 * @id: PCI device ID information
1699 * 1699 *
1700 * This routine performs all the steps necessary to bring the IOC of 1700 * This routine performs all the steps necessary to bring the IOC of
1701 * a MPT adapter to a OPERATIONAL state. This includes registering 1701 * a MPT adapter to a OPERATIONAL state. This includes registering
1702 * memory regions, registering the interrupt, and allocating request 1702 * memory regions, registering the interrupt, and allocating request
1703 * and reply memory pools. 1703 * and reply memory pools.
1704 * 1704 *
1705 * This routine also pre-fetches the LAN MAC address of a Fibre Channel 1705 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1706 * MPT adapter. 1706 * MPT adapter.
1707 * 1707 *
1708 * Returns 0 for success, non-zero for failure. 1708 * Returns 0 for success, non-zero for failure.
1709 * 1709 *
1710 * TODO: Add support for polled controllers 1710 * TODO: Add support for polled controllers
1711 */ 1711 */
1712 int 1712 int
1713 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) 1713 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1714 { 1714 {
1715 MPT_ADAPTER *ioc; 1715 MPT_ADAPTER *ioc;
1716 u8 cb_idx; 1716 u8 cb_idx;
1717 int r = -ENODEV; 1717 int r = -ENODEV;
1718 u8 revision; 1718 u8 revision;
1719 u8 pcixcmd; 1719 u8 pcixcmd;
1720 static int mpt_ids = 0; 1720 static int mpt_ids = 0;
1721 #ifdef CONFIG_PROC_FS 1721 #ifdef CONFIG_PROC_FS
1722 struct proc_dir_entry *dent, *ent; 1722 struct proc_dir_entry *dent, *ent;
1723 #endif 1723 #endif
1724 1724
1725 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); 1725 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1726 if (ioc == NULL) { 1726 if (ioc == NULL) {
1727 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); 1727 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1728 return -ENOMEM; 1728 return -ENOMEM;
1729 } 1729 }
1730 1730
1731 ioc->id = mpt_ids++; 1731 ioc->id = mpt_ids++;
1732 sprintf(ioc->name, "ioc%d", ioc->id); 1732 sprintf(ioc->name, "ioc%d", ioc->id);
1733 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n")); 1733 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1734 1734
1735 /* 1735 /*
1736 * set initial debug level 1736 * set initial debug level
1737 * (refer to mptdebug.h) 1737 * (refer to mptdebug.h)
1738 * 1738 *
1739 */ 1739 */
1740 ioc->debug_level = mpt_debug_level; 1740 ioc->debug_level = mpt_debug_level;
1741 if (mpt_debug_level) 1741 if (mpt_debug_level)
1742 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level); 1742 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1743 1743
1744 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); 1744 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1745 1745
1746 ioc->pcidev = pdev; 1746 ioc->pcidev = pdev;
1747 if (mpt_mapresources(ioc)) { 1747 if (mpt_mapresources(ioc)) {
1748 kfree(ioc); 1748 kfree(ioc);
1749 return r; 1749 return r;
1750 } 1750 }
1751 1751
1752 /* 1752 /*
1753 * Setting up proper handlers for scatter gather handling 1753 * Setting up proper handlers for scatter gather handling
1754 */ 1754 */
1755 if (ioc->dma_mask == DMA_BIT_MASK(64)) { 1755 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1756 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) 1756 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1757 ioc->add_sge = &mpt_add_sge_64bit_1078; 1757 ioc->add_sge = &mpt_add_sge_64bit_1078;
1758 else 1758 else
1759 ioc->add_sge = &mpt_add_sge_64bit; 1759 ioc->add_sge = &mpt_add_sge_64bit;
1760 ioc->add_chain = &mpt_add_chain_64bit; 1760 ioc->add_chain = &mpt_add_chain_64bit;
1761 ioc->sg_addr_size = 8; 1761 ioc->sg_addr_size = 8;
1762 } else { 1762 } else {
1763 ioc->add_sge = &mpt_add_sge; 1763 ioc->add_sge = &mpt_add_sge;
1764 ioc->add_chain = &mpt_add_chain; 1764 ioc->add_chain = &mpt_add_chain;
1765 ioc->sg_addr_size = 4; 1765 ioc->sg_addr_size = 4;
1766 } 1766 }
1767 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size; 1767 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1768 1768
1769 ioc->alloc_total = sizeof(MPT_ADAPTER); 1769 ioc->alloc_total = sizeof(MPT_ADAPTER);
1770 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ 1770 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1771 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1771 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1772 1772
1773 ioc->pcidev = pdev; 1773 ioc->pcidev = pdev;
1774 1774
1775 spin_lock_init(&ioc->taskmgmt_lock); 1775 spin_lock_init(&ioc->taskmgmt_lock);
1776 mutex_init(&ioc->internal_cmds.mutex); 1776 mutex_init(&ioc->internal_cmds.mutex);
1777 init_completion(&ioc->internal_cmds.done); 1777 init_completion(&ioc->internal_cmds.done);
1778 mutex_init(&ioc->mptbase_cmds.mutex); 1778 mutex_init(&ioc->mptbase_cmds.mutex);
1779 init_completion(&ioc->mptbase_cmds.done); 1779 init_completion(&ioc->mptbase_cmds.done);
1780 mutex_init(&ioc->taskmgmt_cmds.mutex); 1780 mutex_init(&ioc->taskmgmt_cmds.mutex);
1781 init_completion(&ioc->taskmgmt_cmds.done); 1781 init_completion(&ioc->taskmgmt_cmds.done);
1782 1782
1783 /* Initialize the event logging. 1783 /* Initialize the event logging.
1784 */ 1784 */
1785 ioc->eventTypes = 0; /* None */ 1785 ioc->eventTypes = 0; /* None */
1786 ioc->eventContext = 0; 1786 ioc->eventContext = 0;
1787 ioc->eventLogSize = 0; 1787 ioc->eventLogSize = 0;
1788 ioc->events = NULL; 1788 ioc->events = NULL;
1789 1789
1790 #ifdef MFCNT 1790 #ifdef MFCNT
1791 ioc->mfcnt = 0; 1791 ioc->mfcnt = 0;
1792 #endif 1792 #endif
1793 1793
1794 ioc->sh = NULL; 1794 ioc->sh = NULL;
1795 ioc->cached_fw = NULL; 1795 ioc->cached_fw = NULL;
1796 1796
1797 /* Initilize SCSI Config Data structure 1797 /* Initilize SCSI Config Data structure
1798 */ 1798 */
1799 memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); 1799 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1800 1800
1801 /* Initialize the fc rport list head. 1801 /* Initialize the fc rport list head.
1802 */ 1802 */
1803 INIT_LIST_HEAD(&ioc->fc_rports); 1803 INIT_LIST_HEAD(&ioc->fc_rports);
1804 1804
1805 /* Find lookup slot. */ 1805 /* Find lookup slot. */
1806 INIT_LIST_HEAD(&ioc->list); 1806 INIT_LIST_HEAD(&ioc->list);
1807 1807
1808 1808
1809 /* Initialize workqueue */ 1809 /* Initialize workqueue */
1810 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work); 1810 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1811 1811
1812 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN, 1812 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1813 "mpt_poll_%d", ioc->id); 1813 "mpt_poll_%d", ioc->id);
1814 ioc->reset_work_q = 1814 ioc->reset_work_q =
1815 create_singlethread_workqueue(ioc->reset_work_q_name); 1815 create_singlethread_workqueue(ioc->reset_work_q_name);
1816 if (!ioc->reset_work_q) { 1816 if (!ioc->reset_work_q) {
1817 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n", 1817 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1818 ioc->name); 1818 ioc->name);
1819 pci_release_selected_regions(pdev, ioc->bars); 1819 pci_release_selected_regions(pdev, ioc->bars);
1820 kfree(ioc); 1820 kfree(ioc);
1821 return -ENOMEM; 1821 return -ENOMEM;
1822 } 1822 }
1823 1823
1824 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", 1824 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1825 ioc->name, &ioc->facts, &ioc->pfacts[0])); 1825 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1826 1826
1827 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 1827 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1828 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name); 1828 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1829 1829
1830 switch (pdev->device) 1830 switch (pdev->device)
1831 { 1831 {
1832 case MPI_MANUFACTPAGE_DEVICEID_FC939X: 1832 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1833 case MPI_MANUFACTPAGE_DEVICEID_FC949X: 1833 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1834 ioc->errata_flag_1064 = 1; 1834 ioc->errata_flag_1064 = 1;
1835 case MPI_MANUFACTPAGE_DEVICEID_FC909: 1835 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1836 case MPI_MANUFACTPAGE_DEVICEID_FC929: 1836 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1837 case MPI_MANUFACTPAGE_DEVICEID_FC919: 1837 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1838 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1838 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1839 ioc->bus_type = FC; 1839 ioc->bus_type = FC;
1840 break; 1840 break;
1841 1841
1842 case MPI_MANUFACTPAGE_DEVICEID_FC929X: 1842 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1843 if (revision < XL_929) { 1843 if (revision < XL_929) {
1844 /* 929X Chip Fix. Set Split transactions level 1844 /* 929X Chip Fix. Set Split transactions level
1845 * for PCIX. Set MOST bits to zero. 1845 * for PCIX. Set MOST bits to zero.
1846 */ 1846 */
1847 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1847 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1848 pcixcmd &= 0x8F; 1848 pcixcmd &= 0x8F;
1849 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1849 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1850 } else { 1850 } else {
1851 /* 929XL Chip Fix. Set MMRBC to 0x08. 1851 /* 929XL Chip Fix. Set MMRBC to 0x08.
1852 */ 1852 */
1853 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1853 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1854 pcixcmd |= 0x08; 1854 pcixcmd |= 0x08;
1855 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1855 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1856 } 1856 }
1857 ioc->bus_type = FC; 1857 ioc->bus_type = FC;
1858 break; 1858 break;
1859 1859
1860 case MPI_MANUFACTPAGE_DEVICEID_FC919X: 1860 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1861 /* 919X Chip Fix. Set Split transactions level 1861 /* 919X Chip Fix. Set Split transactions level
1862 * for PCIX. Set MOST bits to zero. 1862 * for PCIX. Set MOST bits to zero.
1863 */ 1863 */
1864 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1864 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1865 pcixcmd &= 0x8F; 1865 pcixcmd &= 0x8F;
1866 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1866 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1867 ioc->bus_type = FC; 1867 ioc->bus_type = FC;
1868 break; 1868 break;
1869 1869
1870 case MPI_MANUFACTPAGE_DEVID_53C1030: 1870 case MPI_MANUFACTPAGE_DEVID_53C1030:
1871 /* 1030 Chip Fix. Disable Split transactions 1871 /* 1030 Chip Fix. Disable Split transactions
1872 * for PCIX. Set MOST bits to zero if Rev < C0( = 8). 1872 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1873 */ 1873 */
1874 if (revision < C0_1030) { 1874 if (revision < C0_1030) {
1875 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1875 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1876 pcixcmd &= 0x8F; 1876 pcixcmd &= 0x8F;
1877 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1877 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1878 } 1878 }
1879 1879
1880 case MPI_MANUFACTPAGE_DEVID_1030_53C1035: 1880 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1881 ioc->bus_type = SPI; 1881 ioc->bus_type = SPI;
1882 break; 1882 break;
1883 1883
1884 case MPI_MANUFACTPAGE_DEVID_SAS1064: 1884 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1885 case MPI_MANUFACTPAGE_DEVID_SAS1068: 1885 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1886 ioc->errata_flag_1064 = 1; 1886 ioc->errata_flag_1064 = 1;
1887 ioc->bus_type = SAS; 1887 ioc->bus_type = SAS;
1888 break; 1888 break;
1889 1889
1890 case MPI_MANUFACTPAGE_DEVID_SAS1064E: 1890 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1891 case MPI_MANUFACTPAGE_DEVID_SAS1068E: 1891 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1892 case MPI_MANUFACTPAGE_DEVID_SAS1078: 1892 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1893 ioc->bus_type = SAS; 1893 ioc->bus_type = SAS;
1894 break; 1894 break;
1895 } 1895 }
1896 1896
1897 1897
1898 switch (ioc->bus_type) { 1898 switch (ioc->bus_type) {
1899 1899
1900 case SAS: 1900 case SAS:
1901 ioc->msi_enable = mpt_msi_enable_sas; 1901 ioc->msi_enable = mpt_msi_enable_sas;
1902 break; 1902 break;
1903 1903
1904 case SPI: 1904 case SPI:
1905 ioc->msi_enable = mpt_msi_enable_spi; 1905 ioc->msi_enable = mpt_msi_enable_spi;
1906 break; 1906 break;
1907 1907
1908 case FC: 1908 case FC:
1909 ioc->msi_enable = mpt_msi_enable_fc; 1909 ioc->msi_enable = mpt_msi_enable_fc;
1910 break; 1910 break;
1911 1911
1912 default: 1912 default:
1913 ioc->msi_enable = 0; 1913 ioc->msi_enable = 0;
1914 break; 1914 break;
1915 } 1915 }
1916 1916
1917 ioc->fw_events_off = 1; 1917 ioc->fw_events_off = 1;
1918 1918
1919 if (ioc->errata_flag_1064) 1919 if (ioc->errata_flag_1064)
1920 pci_disable_io_access(pdev); 1920 pci_disable_io_access(pdev);
1921 1921
1922 spin_lock_init(&ioc->FreeQlock); 1922 spin_lock_init(&ioc->FreeQlock);
1923 1923
1924 /* Disable all! */ 1924 /* Disable all! */
1925 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 1925 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1926 ioc->active = 0; 1926 ioc->active = 0;
1927 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1927 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1928 1928
1929 /* Set IOC ptr in the pcidev's driver data. */ 1929 /* Set IOC ptr in the pcidev's driver data. */
1930 pci_set_drvdata(ioc->pcidev, ioc); 1930 pci_set_drvdata(ioc->pcidev, ioc);
1931 1931
1932 /* Set lookup ptr. */ 1932 /* Set lookup ptr. */
1933 list_add_tail(&ioc->list, &ioc_list); 1933 list_add_tail(&ioc->list, &ioc_list);
1934 1934
1935 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets. 1935 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1936 */ 1936 */
1937 mpt_detect_bound_ports(ioc, pdev); 1937 mpt_detect_bound_ports(ioc, pdev);
1938 1938
1939 INIT_LIST_HEAD(&ioc->fw_event_list); 1939 INIT_LIST_HEAD(&ioc->fw_event_list);
1940 spin_lock_init(&ioc->fw_event_lock); 1940 spin_lock_init(&ioc->fw_event_lock);
1941 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id); 1941 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1942 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name); 1942 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1943 1943
1944 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 1944 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1945 CAN_SLEEP)) != 0){ 1945 CAN_SLEEP)) != 0){
1946 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n", 1946 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1947 ioc->name, r); 1947 ioc->name, r);
1948 1948
1949 list_del(&ioc->list); 1949 list_del(&ioc->list);
1950 if (ioc->alt_ioc) 1950 if (ioc->alt_ioc)
1951 ioc->alt_ioc->alt_ioc = NULL; 1951 ioc->alt_ioc->alt_ioc = NULL;
1952 iounmap(ioc->memmap); 1952 iounmap(ioc->memmap);
1953 if (r != -5) 1953 if (r != -5)
1954 pci_release_selected_regions(pdev, ioc->bars); 1954 pci_release_selected_regions(pdev, ioc->bars);
1955 1955
1956 destroy_workqueue(ioc->reset_work_q); 1956 destroy_workqueue(ioc->reset_work_q);
1957 ioc->reset_work_q = NULL; 1957 ioc->reset_work_q = NULL;
1958 1958
1959 kfree(ioc); 1959 kfree(ioc);
1960 pci_set_drvdata(pdev, NULL); 1960 pci_set_drvdata(pdev, NULL);
1961 return r; 1961 return r;
1962 } 1962 }
1963 1963
1964 /* call per device driver probe entry point */ 1964 /* call per device driver probe entry point */
1965 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 1965 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1966 if(MptDeviceDriverHandlers[cb_idx] && 1966 if(MptDeviceDriverHandlers[cb_idx] &&
1967 MptDeviceDriverHandlers[cb_idx]->probe) { 1967 MptDeviceDriverHandlers[cb_idx]->probe) {
1968 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id); 1968 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1969 } 1969 }
1970 } 1970 }
1971 1971
1972 #ifdef CONFIG_PROC_FS 1972 #ifdef CONFIG_PROC_FS
1973 /* 1973 /*
1974 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter. 1974 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1975 */ 1975 */
1976 dent = proc_mkdir(ioc->name, mpt_proc_root_dir); 1976 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1977 if (dent) { 1977 if (dent) {
1978 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent); 1978 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1979 if (ent) { 1979 if (ent) {
1980 ent->read_proc = procmpt_iocinfo_read; 1980 ent->read_proc = procmpt_iocinfo_read;
1981 ent->data = ioc; 1981 ent->data = ioc;
1982 } 1982 }
1983 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent); 1983 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1984 if (ent) { 1984 if (ent) {
1985 ent->read_proc = procmpt_summary_read; 1985 ent->read_proc = procmpt_summary_read;
1986 ent->data = ioc; 1986 ent->data = ioc;
1987 } 1987 }
1988 } 1988 }
1989 #endif 1989 #endif
1990 1990
1991 if (!ioc->alt_ioc) 1991 if (!ioc->alt_ioc)
1992 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, 1992 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1993 msecs_to_jiffies(MPT_POLLING_INTERVAL)); 1993 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1994 1994
1995 return 0; 1995 return 0;
1996 } 1996 }
1997 1997
1998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1999 /** 1999 /**
2000 * mpt_detach - Remove a PCI intelligent MPT adapter. 2000 * mpt_detach - Remove a PCI intelligent MPT adapter.
2001 * @pdev: Pointer to pci_dev structure 2001 * @pdev: Pointer to pci_dev structure
2002 */ 2002 */
2003 2003
2004 void 2004 void
2005 mpt_detach(struct pci_dev *pdev) 2005 mpt_detach(struct pci_dev *pdev)
2006 { 2006 {
2007 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 2007 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2008 char pname[32]; 2008 char pname[32];
2009 u8 cb_idx; 2009 u8 cb_idx;
2010 unsigned long flags; 2010 unsigned long flags;
2011 struct workqueue_struct *wq; 2011 struct workqueue_struct *wq;
2012 2012
2013 /* 2013 /*
2014 * Stop polling ioc for fault condition 2014 * Stop polling ioc for fault condition
2015 */ 2015 */
2016 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 2016 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2017 wq = ioc->reset_work_q; 2017 wq = ioc->reset_work_q;
2018 ioc->reset_work_q = NULL; 2018 ioc->reset_work_q = NULL;
2019 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 2019 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2020 cancel_delayed_work(&ioc->fault_reset_work); 2020 cancel_delayed_work(&ioc->fault_reset_work);
2021 destroy_workqueue(wq); 2021 destroy_workqueue(wq);
2022 2022
2023 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2023 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2024 wq = ioc->fw_event_q; 2024 wq = ioc->fw_event_q;
2025 ioc->fw_event_q = NULL; 2025 ioc->fw_event_q = NULL;
2026 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2026 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2027 destroy_workqueue(wq); 2027 destroy_workqueue(wq);
2028 2028
2029 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name); 2029 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2030 remove_proc_entry(pname, NULL); 2030 remove_proc_entry(pname, NULL);
2031 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name); 2031 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2032 remove_proc_entry(pname, NULL); 2032 remove_proc_entry(pname, NULL);
2033 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name); 2033 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2034 remove_proc_entry(pname, NULL); 2034 remove_proc_entry(pname, NULL);
2035 2035
2036 /* call per device driver remove entry point */ 2036 /* call per device driver remove entry point */
2037 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 2037 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2038 if(MptDeviceDriverHandlers[cb_idx] && 2038 if(MptDeviceDriverHandlers[cb_idx] &&
2039 MptDeviceDriverHandlers[cb_idx]->remove) { 2039 MptDeviceDriverHandlers[cb_idx]->remove) {
2040 MptDeviceDriverHandlers[cb_idx]->remove(pdev); 2040 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2041 } 2041 }
2042 } 2042 }
2043 2043
2044 /* Disable interrupts! */ 2044 /* Disable interrupts! */
2045 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2045 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2046 2046
2047 ioc->active = 0; 2047 ioc->active = 0;
2048 synchronize_irq(pdev->irq); 2048 synchronize_irq(pdev->irq);
2049 2049
2050 /* Clear any lingering interrupt */ 2050 /* Clear any lingering interrupt */
2051 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2051 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2052 2052
2053 CHIPREG_READ32(&ioc->chip->IntStatus); 2053 CHIPREG_READ32(&ioc->chip->IntStatus);
2054 2054
2055 mpt_adapter_dispose(ioc); 2055 mpt_adapter_dispose(ioc);
2056 2056
2057 pci_set_drvdata(pdev, NULL); 2057 pci_set_drvdata(pdev, NULL);
2058 } 2058 }
2059 2059
2060 /************************************************************************** 2060 /**************************************************************************
2061 * Power Management 2061 * Power Management
2062 */ 2062 */
2063 #ifdef CONFIG_PM 2063 #ifdef CONFIG_PM
2064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2065 /** 2065 /**
2066 * mpt_suspend - Fusion MPT base driver suspend routine. 2066 * mpt_suspend - Fusion MPT base driver suspend routine.
2067 * @pdev: Pointer to pci_dev structure 2067 * @pdev: Pointer to pci_dev structure
2068 * @state: new state to enter 2068 * @state: new state to enter
2069 */ 2069 */
2070 int 2070 int
2071 mpt_suspend(struct pci_dev *pdev, pm_message_t state) 2071 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2072 { 2072 {
2073 u32 device_state; 2073 u32 device_state;
2074 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 2074 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2075 2075
2076 device_state = pci_choose_state(pdev, state); 2076 device_state = pci_choose_state(pdev, state);
2077 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering " 2077 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2078 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), 2078 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2079 device_state); 2079 device_state);
2080 2080
2081 /* put ioc into READY_STATE */ 2081 /* put ioc into READY_STATE */
2082 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) { 2082 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2083 printk(MYIOC_s_ERR_FMT 2083 printk(MYIOC_s_ERR_FMT
2084 "pci-suspend: IOC msg unit reset failed!\n", ioc->name); 2084 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2085 } 2085 }
2086 2086
2087 /* disable interrupts */ 2087 /* disable interrupts */
2088 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2088 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2089 ioc->active = 0; 2089 ioc->active = 0;
2090 2090
2091 /* Clear any lingering interrupt */ 2091 /* Clear any lingering interrupt */
2092 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2092 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2093 2093
2094 free_irq(ioc->pci_irq, ioc); 2094 free_irq(ioc->pci_irq, ioc);
2095 if (ioc->msi_enable) 2095 if (ioc->msi_enable)
2096 pci_disable_msi(ioc->pcidev); 2096 pci_disable_msi(ioc->pcidev);
2097 ioc->pci_irq = -1; 2097 ioc->pci_irq = -1;
2098 pci_save_state(pdev); 2098 pci_save_state(pdev);
2099 pci_disable_device(pdev); 2099 pci_disable_device(pdev);
2100 pci_release_selected_regions(pdev, ioc->bars); 2100 pci_release_selected_regions(pdev, ioc->bars);
2101 pci_set_power_state(pdev, device_state); 2101 pci_set_power_state(pdev, device_state);
2102 return 0; 2102 return 0;
2103 } 2103 }
2104 2104
2105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2106 /** 2106 /**
2107 * mpt_resume - Fusion MPT base driver resume routine. 2107 * mpt_resume - Fusion MPT base driver resume routine.
2108 * @pdev: Pointer to pci_dev structure 2108 * @pdev: Pointer to pci_dev structure
2109 */ 2109 */
2110 int 2110 int
2111 mpt_resume(struct pci_dev *pdev) 2111 mpt_resume(struct pci_dev *pdev)
2112 { 2112 {
2113 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 2113 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2114 u32 device_state = pdev->current_state; 2114 u32 device_state = pdev->current_state;
2115 int recovery_state; 2115 int recovery_state;
2116 int err; 2116 int err;
2117 2117
2118 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous " 2118 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2119 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), 2119 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2120 device_state); 2120 device_state);
2121 2121
2122 pci_set_power_state(pdev, PCI_D0); 2122 pci_set_power_state(pdev, PCI_D0);
2123 pci_enable_wake(pdev, PCI_D0, 0); 2123 pci_enable_wake(pdev, PCI_D0, 0);
2124 pci_restore_state(pdev); 2124 pci_restore_state(pdev);
2125 ioc->pcidev = pdev; 2125 ioc->pcidev = pdev;
2126 err = mpt_mapresources(ioc); 2126 err = mpt_mapresources(ioc);
2127 if (err) 2127 if (err)
2128 return err; 2128 return err;
2129 2129
2130 if (ioc->dma_mask == DMA_BIT_MASK(64)) { 2130 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2131 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) 2131 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2132 ioc->add_sge = &mpt_add_sge_64bit_1078; 2132 ioc->add_sge = &mpt_add_sge_64bit_1078;
2133 else 2133 else
2134 ioc->add_sge = &mpt_add_sge_64bit; 2134 ioc->add_sge = &mpt_add_sge_64bit;
2135 ioc->add_chain = &mpt_add_chain_64bit; 2135 ioc->add_chain = &mpt_add_chain_64bit;
2136 ioc->sg_addr_size = 8; 2136 ioc->sg_addr_size = 8;
2137 } else { 2137 } else {
2138 2138
2139 ioc->add_sge = &mpt_add_sge; 2139 ioc->add_sge = &mpt_add_sge;
2140 ioc->add_chain = &mpt_add_chain; 2140 ioc->add_chain = &mpt_add_chain;
2141 ioc->sg_addr_size = 4; 2141 ioc->sg_addr_size = 4;
2142 } 2142 }
2143 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size; 2143 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2144 2144
2145 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n", 2145 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2146 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT), 2146 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2147 CHIPREG_READ32(&ioc->chip->Doorbell)); 2147 CHIPREG_READ32(&ioc->chip->Doorbell));
2148 2148
2149 /* 2149 /*
2150 * Errata workaround for SAS pci express: 2150 * Errata workaround for SAS pci express:
2151 * Upon returning to the D0 state, the contents of the doorbell will be 2151 * Upon returning to the D0 state, the contents of the doorbell will be
2152 * stale data, and this will incorrectly signal to the host driver that 2152 * stale data, and this will incorrectly signal to the host driver that
2153 * the firmware is ready to process mpt commands. The workaround is 2153 * the firmware is ready to process mpt commands. The workaround is
2154 * to issue a diagnostic reset. 2154 * to issue a diagnostic reset.
2155 */ 2155 */
2156 if (ioc->bus_type == SAS && (pdev->device == 2156 if (ioc->bus_type == SAS && (pdev->device ==
2157 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device == 2157 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2158 MPI_MANUFACTPAGE_DEVID_SAS1064E)) { 2158 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2159 if (KickStart(ioc, 1, CAN_SLEEP) < 0) { 2159 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2160 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n", 2160 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2161 ioc->name); 2161 ioc->name);
2162 goto out; 2162 goto out;
2163 } 2163 }
2164 } 2164 }
2165 2165
2166 /* bring ioc to operational state */ 2166 /* bring ioc to operational state */
2167 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name); 2167 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2168 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 2168 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2169 CAN_SLEEP); 2169 CAN_SLEEP);
2170 if (recovery_state != 0) 2170 if (recovery_state != 0)
2171 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, " 2171 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2172 "error:[%x]\n", ioc->name, recovery_state); 2172 "error:[%x]\n", ioc->name, recovery_state);
2173 else 2173 else
2174 printk(MYIOC_s_INFO_FMT 2174 printk(MYIOC_s_INFO_FMT
2175 "pci-resume: success\n", ioc->name); 2175 "pci-resume: success\n", ioc->name);
2176 out: 2176 out:
2177 return 0; 2177 return 0;
2178 2178
2179 } 2179 }
2180 #endif 2180 #endif
2181 2181
2182 static int 2182 static int
2183 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase) 2183 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2184 { 2184 {
2185 if ((MptDriverClass[index] == MPTSPI_DRIVER && 2185 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2186 ioc->bus_type != SPI) || 2186 ioc->bus_type != SPI) ||
2187 (MptDriverClass[index] == MPTFC_DRIVER && 2187 (MptDriverClass[index] == MPTFC_DRIVER &&
2188 ioc->bus_type != FC) || 2188 ioc->bus_type != FC) ||
2189 (MptDriverClass[index] == MPTSAS_DRIVER && 2189 (MptDriverClass[index] == MPTSAS_DRIVER &&
2190 ioc->bus_type != SAS)) 2190 ioc->bus_type != SAS))
2191 /* make sure we only call the relevant reset handler 2191 /* make sure we only call the relevant reset handler
2192 * for the bus */ 2192 * for the bus */
2193 return 0; 2193 return 0;
2194 return (MptResetHandlers[index])(ioc, reset_phase); 2194 return (MptResetHandlers[index])(ioc, reset_phase);
2195 } 2195 }
2196 2196
2197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2198 /** 2198 /**
2199 * mpt_do_ioc_recovery - Initialize or recover MPT adapter. 2199 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2200 * @ioc: Pointer to MPT adapter structure 2200 * @ioc: Pointer to MPT adapter structure
2201 * @reason: Event word / reason 2201 * @reason: Event word / reason
2202 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. 2202 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2203 * 2203 *
2204 * This routine performs all the steps necessary to bring the IOC 2204 * This routine performs all the steps necessary to bring the IOC
2205 * to a OPERATIONAL state. 2205 * to a OPERATIONAL state.
2206 * 2206 *
2207 * This routine also pre-fetches the LAN MAC address of a Fibre Channel 2207 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2208 * MPT adapter. 2208 * MPT adapter.
2209 * 2209 *
2210 * Returns: 2210 * Returns:
2211 * 0 for success 2211 * 0 for success
2212 * -1 if failed to get board READY 2212 * -1 if failed to get board READY
2213 * -2 if READY but IOCFacts Failed 2213 * -2 if READY but IOCFacts Failed
2214 * -3 if READY but PrimeIOCFifos Failed 2214 * -3 if READY but PrimeIOCFifos Failed
2215 * -4 if READY but IOCInit Failed 2215 * -4 if READY but IOCInit Failed
2216 * -5 if failed to enable_device and/or request_selected_regions 2216 * -5 if failed to enable_device and/or request_selected_regions
2217 * -6 if failed to upload firmware 2217 * -6 if failed to upload firmware
2218 */ 2218 */
2219 static int 2219 static int
2220 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) 2220 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2221 { 2221 {
2222 int hard_reset_done = 0; 2222 int hard_reset_done = 0;
2223 int alt_ioc_ready = 0; 2223 int alt_ioc_ready = 0;
2224 int hard; 2224 int hard;
2225 int rc=0; 2225 int rc=0;
2226 int ii; 2226 int ii;
2227 int ret = 0; 2227 int ret = 0;
2228 int reset_alt_ioc_active = 0; 2228 int reset_alt_ioc_active = 0;
2229 int irq_allocated = 0; 2229 int irq_allocated = 0;
2230 u8 *a; 2230 u8 *a;
2231 2231
2232 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name, 2232 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2233 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); 2233 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2234 2234
2235 /* Disable reply interrupts (also blocks FreeQ) */ 2235 /* Disable reply interrupts (also blocks FreeQ) */
2236 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2236 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2237 ioc->active = 0; 2237 ioc->active = 0;
2238 2238
2239 if (ioc->alt_ioc) { 2239 if (ioc->alt_ioc) {
2240 if (ioc->alt_ioc->active || 2240 if (ioc->alt_ioc->active ||
2241 reason == MPT_HOSTEVENT_IOC_RECOVER) { 2241 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2242 reset_alt_ioc_active = 1; 2242 reset_alt_ioc_active = 1;
2243 /* Disable alt-IOC's reply interrupts 2243 /* Disable alt-IOC's reply interrupts
2244 * (and FreeQ) for a bit 2244 * (and FreeQ) for a bit
2245 **/ 2245 **/
2246 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 2246 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2247 0xFFFFFFFF); 2247 0xFFFFFFFF);
2248 ioc->alt_ioc->active = 0; 2248 ioc->alt_ioc->active = 0;
2249 } 2249 }
2250 } 2250 }
2251 2251
2252 hard = 1; 2252 hard = 1;
2253 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) 2253 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2254 hard = 0; 2254 hard = 0;
2255 2255
2256 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) { 2256 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2257 if (hard_reset_done == -4) { 2257 if (hard_reset_done == -4) {
2258 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n", 2258 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2259 ioc->name); 2259 ioc->name);
2260 2260
2261 if (reset_alt_ioc_active && ioc->alt_ioc) { 2261 if (reset_alt_ioc_active && ioc->alt_ioc) {
2262 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */ 2262 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2263 dprintk(ioc, printk(MYIOC_s_INFO_FMT 2263 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2264 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name)); 2264 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2265 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM); 2265 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2266 ioc->alt_ioc->active = 1; 2266 ioc->alt_ioc->active = 1;
2267 } 2267 }
2268 2268
2269 } else { 2269 } else {
2270 printk(MYIOC_s_WARN_FMT 2270 printk(MYIOC_s_WARN_FMT
2271 "NOT READY WARNING!\n", ioc->name); 2271 "NOT READY WARNING!\n", ioc->name);
2272 } 2272 }
2273 ret = -1; 2273 ret = -1;
2274 goto out; 2274 goto out;
2275 } 2275 }
2276 2276
2277 /* hard_reset_done = 0 if a soft reset was performed 2277 /* hard_reset_done = 0 if a soft reset was performed
2278 * and 1 if a hard reset was performed. 2278 * and 1 if a hard reset was performed.
2279 */ 2279 */
2280 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) { 2280 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2281 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0) 2281 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2282 alt_ioc_ready = 1; 2282 alt_ioc_ready = 1;
2283 else 2283 else
2284 printk(MYIOC_s_WARN_FMT 2284 printk(MYIOC_s_WARN_FMT
2285 ": alt-ioc Not ready WARNING!\n", 2285 ": alt-ioc Not ready WARNING!\n",
2286 ioc->alt_ioc->name); 2286 ioc->alt_ioc->name);
2287 } 2287 }
2288 2288
2289 for (ii=0; ii<5; ii++) { 2289 for (ii=0; ii<5; ii++) {
2290 /* Get IOC facts! Allow 5 retries */ 2290 /* Get IOC facts! Allow 5 retries */
2291 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0) 2291 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2292 break; 2292 break;
2293 } 2293 }
2294 2294
2295 2295
2296 if (ii == 5) { 2296 if (ii == 5) {
2297 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2297 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2298 "Retry IocFacts failed rc=%x\n", ioc->name, rc)); 2298 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2299 ret = -2; 2299 ret = -2;
2300 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2300 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2301 MptDisplayIocCapabilities(ioc); 2301 MptDisplayIocCapabilities(ioc);
2302 } 2302 }
2303 2303
2304 if (alt_ioc_ready) { 2304 if (alt_ioc_ready) {
2305 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { 2305 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2306 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2306 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2307 "Initial Alt IocFacts failed rc=%x\n", 2307 "Initial Alt IocFacts failed rc=%x\n",
2308 ioc->name, rc)); 2308 ioc->name, rc));
2309 /* Retry - alt IOC was initialized once 2309 /* Retry - alt IOC was initialized once
2310 */ 2310 */
2311 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); 2311 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2312 } 2312 }
2313 if (rc) { 2313 if (rc) {
2314 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2314 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2315 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc)); 2315 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2316 alt_ioc_ready = 0; 2316 alt_ioc_ready = 0;
2317 reset_alt_ioc_active = 0; 2317 reset_alt_ioc_active = 0;
2318 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2318 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2319 MptDisplayIocCapabilities(ioc->alt_ioc); 2319 MptDisplayIocCapabilities(ioc->alt_ioc);
2320 } 2320 }
2321 } 2321 }
2322 2322
2323 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) && 2323 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2324 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) { 2324 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2325 pci_release_selected_regions(ioc->pcidev, ioc->bars); 2325 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2326 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM | 2326 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2327 IORESOURCE_IO); 2327 IORESOURCE_IO);
2328 if (pci_enable_device(ioc->pcidev)) 2328 if (pci_enable_device(ioc->pcidev))
2329 return -5; 2329 return -5;
2330 if (pci_request_selected_regions(ioc->pcidev, ioc->bars, 2330 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2331 "mpt")) 2331 "mpt"))
2332 return -5; 2332 return -5;
2333 } 2333 }
2334 2334
2335 /* 2335 /*
2336 * Device is reset now. It must have de-asserted the interrupt line 2336 * Device is reset now. It must have de-asserted the interrupt line
2337 * (if it was asserted) and it should be safe to register for the 2337 * (if it was asserted) and it should be safe to register for the
2338 * interrupt now. 2338 * interrupt now.
2339 */ 2339 */
2340 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 2340 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2341 ioc->pci_irq = -1; 2341 ioc->pci_irq = -1;
2342 if (ioc->pcidev->irq) { 2342 if (ioc->pcidev->irq) {
2343 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev)) 2343 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2344 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", 2344 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2345 ioc->name); 2345 ioc->name);
2346 else 2346 else
2347 ioc->msi_enable = 0; 2347 ioc->msi_enable = 0;
2348 rc = request_irq(ioc->pcidev->irq, mpt_interrupt, 2348 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2349 IRQF_SHARED, ioc->name, ioc); 2349 IRQF_SHARED, ioc->name, ioc);
2350 if (rc < 0) { 2350 if (rc < 0) {
2351 printk(MYIOC_s_ERR_FMT "Unable to allocate " 2351 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2352 "interrupt %d!\n", 2352 "interrupt %d!\n",
2353 ioc->name, ioc->pcidev->irq); 2353 ioc->name, ioc->pcidev->irq);
2354 if (ioc->msi_enable) 2354 if (ioc->msi_enable)
2355 pci_disable_msi(ioc->pcidev); 2355 pci_disable_msi(ioc->pcidev);
2356 ret = -EBUSY; 2356 ret = -EBUSY;
2357 goto out; 2357 goto out;
2358 } 2358 }
2359 irq_allocated = 1; 2359 irq_allocated = 1;
2360 ioc->pci_irq = ioc->pcidev->irq; 2360 ioc->pci_irq = ioc->pcidev->irq;
2361 pci_set_master(ioc->pcidev); /* ?? */ 2361 pci_set_master(ioc->pcidev); /* ?? */
2362 pci_set_drvdata(ioc->pcidev, ioc); 2362 pci_set_drvdata(ioc->pcidev, ioc);
2363 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2363 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2364 "installed at interrupt %d\n", ioc->name, 2364 "installed at interrupt %d\n", ioc->name,
2365 ioc->pcidev->irq)); 2365 ioc->pcidev->irq));
2366 } 2366 }
2367 } 2367 }
2368 2368
2369 /* Prime reply & request queues! 2369 /* Prime reply & request queues!
2370 * (mucho alloc's) Must be done prior to 2370 * (mucho alloc's) Must be done prior to
2371 * init as upper addresses are needed for init. 2371 * init as upper addresses are needed for init.
2372 * If fails, continue with alt-ioc processing 2372 * If fails, continue with alt-ioc processing
2373 */ 2373 */
2374 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n", 2374 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2375 ioc->name)); 2375 ioc->name));
2376 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0)) 2376 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2377 ret = -3; 2377 ret = -3;
2378 2378
2379 /* May need to check/upload firmware & data here! 2379 /* May need to check/upload firmware & data here!
2380 * If fails, continue with alt-ioc processing 2380 * If fails, continue with alt-ioc processing
2381 */ 2381 */
2382 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n", 2382 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2383 ioc->name)); 2383 ioc->name));
2384 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0)) 2384 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2385 ret = -4; 2385 ret = -4;
2386 // NEW! 2386 // NEW!
2387 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) { 2387 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2388 printk(MYIOC_s_WARN_FMT 2388 printk(MYIOC_s_WARN_FMT
2389 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n", 2389 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2390 ioc->alt_ioc->name, rc); 2390 ioc->alt_ioc->name, rc);
2391 alt_ioc_ready = 0; 2391 alt_ioc_ready = 0;
2392 reset_alt_ioc_active = 0; 2392 reset_alt_ioc_active = 0;
2393 } 2393 }
2394 2394
2395 if (alt_ioc_ready) { 2395 if (alt_ioc_ready) {
2396 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) { 2396 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2397 alt_ioc_ready = 0; 2397 alt_ioc_ready = 0;
2398 reset_alt_ioc_active = 0; 2398 reset_alt_ioc_active = 0;
2399 printk(MYIOC_s_WARN_FMT 2399 printk(MYIOC_s_WARN_FMT
2400 ": alt-ioc: (%d) init failure WARNING!\n", 2400 ": alt-ioc: (%d) init failure WARNING!\n",
2401 ioc->alt_ioc->name, rc); 2401 ioc->alt_ioc->name, rc);
2402 } 2402 }
2403 } 2403 }
2404 2404
2405 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){ 2405 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2406 if (ioc->upload_fw) { 2406 if (ioc->upload_fw) {
2407 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2407 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2408 "firmware upload required!\n", ioc->name)); 2408 "firmware upload required!\n", ioc->name));
2409 2409
2410 /* Controller is not operational, cannot do upload 2410 /* Controller is not operational, cannot do upload
2411 */ 2411 */
2412 if (ret == 0) { 2412 if (ret == 0) {
2413 rc = mpt_do_upload(ioc, sleepFlag); 2413 rc = mpt_do_upload(ioc, sleepFlag);
2414 if (rc == 0) { 2414 if (rc == 0) {
2415 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { 2415 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2416 /* 2416 /*
2417 * Maintain only one pointer to FW memory 2417 * Maintain only one pointer to FW memory
2418 * so there will not be two attempt to 2418 * so there will not be two attempt to
2419 * downloadboot onboard dual function 2419 * downloadboot onboard dual function
2420 * chips (mpt_adapter_disable, 2420 * chips (mpt_adapter_disable,
2421 * mpt_diag_reset) 2421 * mpt_diag_reset)
2422 */ 2422 */
2423 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2423 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2424 "mpt_upload: alt_%s has cached_fw=%p \n", 2424 "mpt_upload: alt_%s has cached_fw=%p \n",
2425 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); 2425 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2426 ioc->cached_fw = NULL; 2426 ioc->cached_fw = NULL;
2427 } 2427 }
2428 } else { 2428 } else {
2429 printk(MYIOC_s_WARN_FMT 2429 printk(MYIOC_s_WARN_FMT
2430 "firmware upload failure!\n", ioc->name); 2430 "firmware upload failure!\n", ioc->name);
2431 ret = -6; 2431 ret = -6;
2432 } 2432 }
2433 } 2433 }
2434 } 2434 }
2435 } 2435 }
2436 2436
2437 /* Enable MPT base driver management of EventNotification 2437 /* Enable MPT base driver management of EventNotification
2438 * and EventAck handling. 2438 * and EventAck handling.
2439 */ 2439 */
2440 if ((ret == 0) && (!ioc->facts.EventState)) { 2440 if ((ret == 0) && (!ioc->facts.EventState)) {
2441 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2441 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2442 "SendEventNotification\n", 2442 "SendEventNotification\n",
2443 ioc->name)); 2443 ioc->name));
2444 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */ 2444 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2445 } 2445 }
2446 2446
2447 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) 2447 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2448 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag); 2448 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2449 2449
2450 if (ret == 0) { 2450 if (ret == 0) {
2451 /* Enable! (reply interrupt) */ 2451 /* Enable! (reply interrupt) */
2452 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); 2452 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2453 ioc->active = 1; 2453 ioc->active = 1;
2454 } 2454 }
2455 if (rc == 0) { /* alt ioc */ 2455 if (rc == 0) { /* alt ioc */
2456 if (reset_alt_ioc_active && ioc->alt_ioc) { 2456 if (reset_alt_ioc_active && ioc->alt_ioc) {
2457 /* (re)Enable alt-IOC! (reply interrupt) */ 2457 /* (re)Enable alt-IOC! (reply interrupt) */
2458 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc" 2458 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2459 "reply irq re-enabled\n", 2459 "reply irq re-enabled\n",
2460 ioc->alt_ioc->name)); 2460 ioc->alt_ioc->name));
2461 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 2461 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2462 MPI_HIM_DIM); 2462 MPI_HIM_DIM);
2463 ioc->alt_ioc->active = 1; 2463 ioc->alt_ioc->active = 1;
2464 } 2464 }
2465 } 2465 }
2466 2466
2467 2467
2468 /* Add additional "reason" check before call to GetLanConfigPages 2468 /* Add additional "reason" check before call to GetLanConfigPages
2469 * (combined with GetIoUnitPage2 call). This prevents a somewhat 2469 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2470 * recursive scenario; GetLanConfigPages times out, timer expired 2470 * recursive scenario; GetLanConfigPages times out, timer expired
2471 * routine calls HardResetHandler, which calls into here again, 2471 * routine calls HardResetHandler, which calls into here again,
2472 * and we try GetLanConfigPages again... 2472 * and we try GetLanConfigPages again...
2473 */ 2473 */
2474 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 2474 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2475 2475
2476 /* 2476 /*
2477 * Initalize link list for inactive raid volumes. 2477 * Initalize link list for inactive raid volumes.
2478 */ 2478 */
2479 mutex_init(&ioc->raid_data.inactive_list_mutex); 2479 mutex_init(&ioc->raid_data.inactive_list_mutex);
2480 INIT_LIST_HEAD(&ioc->raid_data.inactive_list); 2480 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2481 2481
2482 switch (ioc->bus_type) { 2482 switch (ioc->bus_type) {
2483 2483
2484 case SAS: 2484 case SAS:
2485 /* clear persistency table */ 2485 /* clear persistency table */
2486 if(ioc->facts.IOCExceptions & 2486 if(ioc->facts.IOCExceptions &
2487 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) { 2487 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2488 ret = mptbase_sas_persist_operation(ioc, 2488 ret = mptbase_sas_persist_operation(ioc,
2489 MPI_SAS_OP_CLEAR_NOT_PRESENT); 2489 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2490 if(ret != 0) 2490 if(ret != 0)
2491 goto out; 2491 goto out;
2492 } 2492 }
2493 2493
2494 /* Find IM volumes 2494 /* Find IM volumes
2495 */ 2495 */
2496 mpt_findImVolumes(ioc); 2496 mpt_findImVolumes(ioc);
2497 2497
2498 /* Check, and possibly reset, the coalescing value 2498 /* Check, and possibly reset, the coalescing value
2499 */ 2499 */
2500 mpt_read_ioc_pg_1(ioc); 2500 mpt_read_ioc_pg_1(ioc);
2501 2501
2502 break; 2502 break;
2503 2503
2504 case FC: 2504 case FC:
2505 if ((ioc->pfacts[0].ProtocolFlags & 2505 if ((ioc->pfacts[0].ProtocolFlags &
2506 MPI_PORTFACTS_PROTOCOL_LAN) && 2506 MPI_PORTFACTS_PROTOCOL_LAN) &&
2507 (ioc->lan_cnfg_page0.Header.PageLength == 0)) { 2507 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2508 /* 2508 /*
2509 * Pre-fetch the ports LAN MAC address! 2509 * Pre-fetch the ports LAN MAC address!
2510 * (LANPage1_t stuff) 2510 * (LANPage1_t stuff)
2511 */ 2511 */
2512 (void) GetLanConfigPages(ioc); 2512 (void) GetLanConfigPages(ioc);
2513 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 2513 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2514 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2514 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2515 "LanAddr = %02X:%02X:%02X" 2515 "LanAddr = %02X:%02X:%02X"
2516 ":%02X:%02X:%02X\n", 2516 ":%02X:%02X:%02X\n",
2517 ioc->name, a[5], a[4], 2517 ioc->name, a[5], a[4],
2518 a[3], a[2], a[1], a[0])); 2518 a[3], a[2], a[1], a[0]));
2519 } 2519 }
2520 break; 2520 break;
2521 2521
2522 case SPI: 2522 case SPI:
2523 /* Get NVRAM and adapter maximums from SPP 0 and 2 2523 /* Get NVRAM and adapter maximums from SPP 0 and 2
2524 */ 2524 */
2525 mpt_GetScsiPortSettings(ioc, 0); 2525 mpt_GetScsiPortSettings(ioc, 0);
2526 2526
2527 /* Get version and length of SDP 1 2527 /* Get version and length of SDP 1
2528 */ 2528 */
2529 mpt_readScsiDevicePageHeaders(ioc, 0); 2529 mpt_readScsiDevicePageHeaders(ioc, 0);
2530 2530
2531 /* Find IM volumes 2531 /* Find IM volumes
2532 */ 2532 */
2533 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02) 2533 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2534 mpt_findImVolumes(ioc); 2534 mpt_findImVolumes(ioc);
2535 2535
2536 /* Check, and possibly reset, the coalescing value 2536 /* Check, and possibly reset, the coalescing value
2537 */ 2537 */
2538 mpt_read_ioc_pg_1(ioc); 2538 mpt_read_ioc_pg_1(ioc);
2539 2539
2540 mpt_read_ioc_pg_4(ioc); 2540 mpt_read_ioc_pg_4(ioc);
2541 2541
2542 break; 2542 break;
2543 } 2543 }
2544 2544
2545 GetIoUnitPage2(ioc); 2545 GetIoUnitPage2(ioc);
2546 mpt_get_manufacturing_pg_0(ioc); 2546 mpt_get_manufacturing_pg_0(ioc);
2547 } 2547 }
2548 2548
2549 out: 2549 out:
2550 if ((ret != 0) && irq_allocated) { 2550 if ((ret != 0) && irq_allocated) {
2551 free_irq(ioc->pci_irq, ioc); 2551 free_irq(ioc->pci_irq, ioc);
2552 if (ioc->msi_enable) 2552 if (ioc->msi_enable)
2553 pci_disable_msi(ioc->pcidev); 2553 pci_disable_msi(ioc->pcidev);
2554 } 2554 }
2555 return ret; 2555 return ret;
2556 } 2556 }
2557 2557
2558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2559 /** 2559 /**
2560 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function 2560 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2561 * @ioc: Pointer to MPT adapter structure 2561 * @ioc: Pointer to MPT adapter structure
2562 * @pdev: Pointer to (struct pci_dev) structure 2562 * @pdev: Pointer to (struct pci_dev) structure
2563 * 2563 *
2564 * Search for PCI bus/dev_function which matches 2564 * Search for PCI bus/dev_function which matches
2565 * PCI bus/dev_function (+/-1) for newly discovered 929, 2565 * PCI bus/dev_function (+/-1) for newly discovered 929,
2566 * 929X, 1030 or 1035. 2566 * 929X, 1030 or 1035.
2567 * 2567 *
2568 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters 2568 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2569 * using alt_ioc pointer fields in their %MPT_ADAPTER structures. 2569 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2570 */ 2570 */
2571 static void 2571 static void
2572 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) 2572 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2573 { 2573 {
2574 struct pci_dev *peer=NULL; 2574 struct pci_dev *peer=NULL;
2575 unsigned int slot = PCI_SLOT(pdev->devfn); 2575 unsigned int slot = PCI_SLOT(pdev->devfn);
2576 unsigned int func = PCI_FUNC(pdev->devfn); 2576 unsigned int func = PCI_FUNC(pdev->devfn);
2577 MPT_ADAPTER *ioc_srch; 2577 MPT_ADAPTER *ioc_srch;
2578 2578
2579 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x," 2579 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2580 " searching for devfn match on %x or %x\n", 2580 " searching for devfn match on %x or %x\n",
2581 ioc->name, pci_name(pdev), pdev->bus->number, 2581 ioc->name, pci_name(pdev), pdev->bus->number,
2582 pdev->devfn, func-1, func+1)); 2582 pdev->devfn, func-1, func+1));
2583 2583
2584 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1)); 2584 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2585 if (!peer) { 2585 if (!peer) {
2586 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1)); 2586 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2587 if (!peer) 2587 if (!peer)
2588 return; 2588 return;
2589 } 2589 }
2590 2590
2591 list_for_each_entry(ioc_srch, &ioc_list, list) { 2591 list_for_each_entry(ioc_srch, &ioc_list, list) {
2592 struct pci_dev *_pcidev = ioc_srch->pcidev; 2592 struct pci_dev *_pcidev = ioc_srch->pcidev;
2593 if (_pcidev == peer) { 2593 if (_pcidev == peer) {
2594 /* Paranoia checks */ 2594 /* Paranoia checks */
2595 if (ioc->alt_ioc != NULL) { 2595 if (ioc->alt_ioc != NULL) {
2596 printk(MYIOC_s_WARN_FMT 2596 printk(MYIOC_s_WARN_FMT
2597 "Oops, already bound (%s <==> %s)!\n", 2597 "Oops, already bound (%s <==> %s)!\n",
2598 ioc->name, ioc->name, ioc->alt_ioc->name); 2598 ioc->name, ioc->name, ioc->alt_ioc->name);
2599 break; 2599 break;
2600 } else if (ioc_srch->alt_ioc != NULL) { 2600 } else if (ioc_srch->alt_ioc != NULL) {
2601 printk(MYIOC_s_WARN_FMT 2601 printk(MYIOC_s_WARN_FMT
2602 "Oops, already bound (%s <==> %s)!\n", 2602 "Oops, already bound (%s <==> %s)!\n",
2603 ioc_srch->name, ioc_srch->name, 2603 ioc_srch->name, ioc_srch->name,
2604 ioc_srch->alt_ioc->name); 2604 ioc_srch->alt_ioc->name);
2605 break; 2605 break;
2606 } 2606 }
2607 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2607 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2608 "FOUND! binding %s <==> %s\n", 2608 "FOUND! binding %s <==> %s\n",
2609 ioc->name, ioc->name, ioc_srch->name)); 2609 ioc->name, ioc->name, ioc_srch->name));
2610 ioc_srch->alt_ioc = ioc; 2610 ioc_srch->alt_ioc = ioc;
2611 ioc->alt_ioc = ioc_srch; 2611 ioc->alt_ioc = ioc_srch;
2612 } 2612 }
2613 } 2613 }
2614 pci_dev_put(peer); 2614 pci_dev_put(peer);
2615 } 2615 }
2616 2616
2617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2618 /** 2618 /**
2619 * mpt_adapter_disable - Disable misbehaving MPT adapter. 2619 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2620 * @ioc: Pointer to MPT adapter structure 2620 * @ioc: Pointer to MPT adapter structure
2621 */ 2621 */
2622 static void 2622 static void
2623 mpt_adapter_disable(MPT_ADAPTER *ioc) 2623 mpt_adapter_disable(MPT_ADAPTER *ioc)
2624 { 2624 {
2625 int sz; 2625 int sz;
2626 int ret; 2626 int ret;
2627 2627
2628 if (ioc->cached_fw != NULL) { 2628 if (ioc->cached_fw != NULL) {
2629 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2629 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2630 "%s: Pushing FW onto adapter\n", __func__, ioc->name)); 2630 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2631 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) 2631 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2632 ioc->cached_fw, CAN_SLEEP)) < 0) { 2632 ioc->cached_fw, CAN_SLEEP)) < 0) {
2633 printk(MYIOC_s_WARN_FMT 2633 printk(MYIOC_s_WARN_FMT
2634 ": firmware downloadboot failure (%d)!\n", 2634 ": firmware downloadboot failure (%d)!\n",
2635 ioc->name, ret); 2635 ioc->name, ret);
2636 } 2636 }
2637 } 2637 }
2638 2638
2639 /* 2639 /*
2640 * Put the controller into ready state (if its not already) 2640 * Put the controller into ready state (if its not already)
2641 */ 2641 */
2642 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) { 2642 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2643 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, 2643 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2644 CAN_SLEEP)) { 2644 CAN_SLEEP)) {
2645 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) 2645 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2646 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit " 2646 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2647 "reset failed to put ioc in ready state!\n", 2647 "reset failed to put ioc in ready state!\n",
2648 ioc->name, __func__); 2648 ioc->name, __func__);
2649 } else 2649 } else
2650 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset " 2650 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2651 "failed!\n", ioc->name, __func__); 2651 "failed!\n", ioc->name, __func__);
2652 } 2652 }
2653 2653
2654 2654
2655 /* Disable adapter interrupts! */ 2655 /* Disable adapter interrupts! */
2656 synchronize_irq(ioc->pcidev->irq); 2656 synchronize_irq(ioc->pcidev->irq);
2657 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2657 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2658 ioc->active = 0; 2658 ioc->active = 0;
2659 2659
2660 /* Clear any lingering interrupt */ 2660 /* Clear any lingering interrupt */
2661 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2661 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2662 CHIPREG_READ32(&ioc->chip->IntStatus); 2662 CHIPREG_READ32(&ioc->chip->IntStatus);
2663 2663
2664 if (ioc->alloc != NULL) { 2664 if (ioc->alloc != NULL) {
2665 sz = ioc->alloc_sz; 2665 sz = ioc->alloc_sz;
2666 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n", 2666 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2667 ioc->name, ioc->alloc, ioc->alloc_sz)); 2667 ioc->name, ioc->alloc, ioc->alloc_sz));
2668 pci_free_consistent(ioc->pcidev, sz, 2668 pci_free_consistent(ioc->pcidev, sz,
2669 ioc->alloc, ioc->alloc_dma); 2669 ioc->alloc, ioc->alloc_dma);
2670 ioc->reply_frames = NULL; 2670 ioc->reply_frames = NULL;
2671 ioc->req_frames = NULL; 2671 ioc->req_frames = NULL;
2672 ioc->alloc = NULL; 2672 ioc->alloc = NULL;
2673 ioc->alloc_total -= sz; 2673 ioc->alloc_total -= sz;
2674 } 2674 }
2675 2675
2676 if (ioc->sense_buf_pool != NULL) { 2676 if (ioc->sense_buf_pool != NULL) {
2677 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 2677 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2678 pci_free_consistent(ioc->pcidev, sz, 2678 pci_free_consistent(ioc->pcidev, sz,
2679 ioc->sense_buf_pool, ioc->sense_buf_pool_dma); 2679 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2680 ioc->sense_buf_pool = NULL; 2680 ioc->sense_buf_pool = NULL;
2681 ioc->alloc_total -= sz; 2681 ioc->alloc_total -= sz;
2682 } 2682 }
2683 2683
2684 if (ioc->events != NULL){ 2684 if (ioc->events != NULL){
2685 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS); 2685 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2686 kfree(ioc->events); 2686 kfree(ioc->events);
2687 ioc->events = NULL; 2687 ioc->events = NULL;
2688 ioc->alloc_total -= sz; 2688 ioc->alloc_total -= sz;
2689 } 2689 }
2690 2690
2691 mpt_free_fw_memory(ioc); 2691 mpt_free_fw_memory(ioc);
2692 2692
2693 kfree(ioc->spi_data.nvram); 2693 kfree(ioc->spi_data.nvram);
2694 mpt_inactive_raid_list_free(ioc); 2694 mpt_inactive_raid_list_free(ioc);
2695 kfree(ioc->raid_data.pIocPg2); 2695 kfree(ioc->raid_data.pIocPg2);
2696 kfree(ioc->raid_data.pIocPg3); 2696 kfree(ioc->raid_data.pIocPg3);
2697 ioc->spi_data.nvram = NULL; 2697 ioc->spi_data.nvram = NULL;
2698 ioc->raid_data.pIocPg3 = NULL; 2698 ioc->raid_data.pIocPg3 = NULL;
2699 2699
2700 if (ioc->spi_data.pIocPg4 != NULL) { 2700 if (ioc->spi_data.pIocPg4 != NULL) {
2701 sz = ioc->spi_data.IocPg4Sz; 2701 sz = ioc->spi_data.IocPg4Sz;
2702 pci_free_consistent(ioc->pcidev, sz, 2702 pci_free_consistent(ioc->pcidev, sz,
2703 ioc->spi_data.pIocPg4, 2703 ioc->spi_data.pIocPg4,
2704 ioc->spi_data.IocPg4_dma); 2704 ioc->spi_data.IocPg4_dma);
2705 ioc->spi_data.pIocPg4 = NULL; 2705 ioc->spi_data.pIocPg4 = NULL;
2706 ioc->alloc_total -= sz; 2706 ioc->alloc_total -= sz;
2707 } 2707 }
2708 2708
2709 if (ioc->ReqToChain != NULL) { 2709 if (ioc->ReqToChain != NULL) {
2710 kfree(ioc->ReqToChain); 2710 kfree(ioc->ReqToChain);
2711 kfree(ioc->RequestNB); 2711 kfree(ioc->RequestNB);
2712 ioc->ReqToChain = NULL; 2712 ioc->ReqToChain = NULL;
2713 } 2713 }
2714 2714
2715 kfree(ioc->ChainToChain); 2715 kfree(ioc->ChainToChain);
2716 ioc->ChainToChain = NULL; 2716 ioc->ChainToChain = NULL;
2717 2717
2718 if (ioc->HostPageBuffer != NULL) { 2718 if (ioc->HostPageBuffer != NULL) {
2719 if((ret = mpt_host_page_access_control(ioc, 2719 if((ret = mpt_host_page_access_control(ioc,
2720 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) { 2720 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2721 printk(MYIOC_s_ERR_FMT 2721 printk(MYIOC_s_ERR_FMT
2722 ": %s: host page buffers free failed (%d)!\n", 2722 ": %s: host page buffers free failed (%d)!\n",
2723 ioc->name, __func__, ret); 2723 ioc->name, __func__, ret);
2724 } 2724 }
2725 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2725 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2726 "HostPageBuffer free @ %p, sz=%d bytes\n", 2726 "HostPageBuffer free @ %p, sz=%d bytes\n",
2727 ioc->name, ioc->HostPageBuffer, 2727 ioc->name, ioc->HostPageBuffer,
2728 ioc->HostPageBuffer_sz)); 2728 ioc->HostPageBuffer_sz));
2729 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz, 2729 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2730 ioc->HostPageBuffer, ioc->HostPageBuffer_dma); 2730 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2731 ioc->HostPageBuffer = NULL; 2731 ioc->HostPageBuffer = NULL;
2732 ioc->HostPageBuffer_sz = 0; 2732 ioc->HostPageBuffer_sz = 0;
2733 ioc->alloc_total -= ioc->HostPageBuffer_sz; 2733 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2734 } 2734 }
2735 2735
2736 pci_set_drvdata(ioc->pcidev, NULL); 2736 pci_set_drvdata(ioc->pcidev, NULL);
2737 } 2737 }
2738 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2738 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2739 /** 2739 /**
2740 * mpt_adapter_dispose - Free all resources associated with an MPT adapter 2740 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2741 * @ioc: Pointer to MPT adapter structure 2741 * @ioc: Pointer to MPT adapter structure
2742 * 2742 *
2743 * This routine unregisters h/w resources and frees all alloc'd memory 2743 * This routine unregisters h/w resources and frees all alloc'd memory
2744 * associated with a MPT adapter structure. 2744 * associated with a MPT adapter structure.
2745 */ 2745 */
2746 static void 2746 static void
2747 mpt_adapter_dispose(MPT_ADAPTER *ioc) 2747 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2748 { 2748 {
2749 int sz_first, sz_last; 2749 int sz_first, sz_last;
2750 2750
2751 if (ioc == NULL) 2751 if (ioc == NULL)
2752 return; 2752 return;
2753 2753
2754 sz_first = ioc->alloc_total; 2754 sz_first = ioc->alloc_total;
2755 2755
2756 mpt_adapter_disable(ioc); 2756 mpt_adapter_disable(ioc);
2757 2757
2758 if (ioc->pci_irq != -1) { 2758 if (ioc->pci_irq != -1) {
2759 free_irq(ioc->pci_irq, ioc); 2759 free_irq(ioc->pci_irq, ioc);
2760 if (ioc->msi_enable) 2760 if (ioc->msi_enable)
2761 pci_disable_msi(ioc->pcidev); 2761 pci_disable_msi(ioc->pcidev);
2762 ioc->pci_irq = -1; 2762 ioc->pci_irq = -1;
2763 } 2763 }
2764 2764
2765 if (ioc->memmap != NULL) { 2765 if (ioc->memmap != NULL) {
2766 iounmap(ioc->memmap); 2766 iounmap(ioc->memmap);
2767 ioc->memmap = NULL; 2767 ioc->memmap = NULL;
2768 } 2768 }
2769 2769
2770 pci_disable_device(ioc->pcidev); 2770 pci_disable_device(ioc->pcidev);
2771 pci_release_selected_regions(ioc->pcidev, ioc->bars); 2771 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2772 2772
2773 #if defined(CONFIG_MTRR) && 0 2773 #if defined(CONFIG_MTRR) && 0
2774 if (ioc->mtrr_reg > 0) { 2774 if (ioc->mtrr_reg > 0) {
2775 mtrr_del(ioc->mtrr_reg, 0, 0); 2775 mtrr_del(ioc->mtrr_reg, 0, 0);
2776 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name)); 2776 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2777 } 2777 }
2778 #endif 2778 #endif
2779 2779
2780 /* Zap the adapter lookup ptr! */ 2780 /* Zap the adapter lookup ptr! */
2781 list_del(&ioc->list); 2781 list_del(&ioc->list);
2782 2782
2783 sz_last = ioc->alloc_total; 2783 sz_last = ioc->alloc_total;
2784 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n", 2784 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2785 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); 2785 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2786 2786
2787 if (ioc->alt_ioc) 2787 if (ioc->alt_ioc)
2788 ioc->alt_ioc->alt_ioc = NULL; 2788 ioc->alt_ioc->alt_ioc = NULL;
2789 2789
2790 kfree(ioc); 2790 kfree(ioc);
2791 } 2791 }
2792 2792
2793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2794 /** 2794 /**
2795 * MptDisplayIocCapabilities - Disply IOC's capabilities. 2795 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2796 * @ioc: Pointer to MPT adapter structure 2796 * @ioc: Pointer to MPT adapter structure
2797 */ 2797 */
2798 static void 2798 static void
2799 MptDisplayIocCapabilities(MPT_ADAPTER *ioc) 2799 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2800 { 2800 {
2801 int i = 0; 2801 int i = 0;
2802 2802
2803 printk(KERN_INFO "%s: ", ioc->name); 2803 printk(KERN_INFO "%s: ", ioc->name);
2804 if (ioc->prod_name) 2804 if (ioc->prod_name)
2805 printk("%s: ", ioc->prod_name); 2805 printk("%s: ", ioc->prod_name);
2806 printk("Capabilities={"); 2806 printk("Capabilities={");
2807 2807
2808 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) { 2808 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2809 printk("Initiator"); 2809 printk("Initiator");
2810 i++; 2810 i++;
2811 } 2811 }
2812 2812
2813 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) { 2813 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2814 printk("%sTarget", i ? "," : ""); 2814 printk("%sTarget", i ? "," : "");
2815 i++; 2815 i++;
2816 } 2816 }
2817 2817
2818 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { 2818 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2819 printk("%sLAN", i ? "," : ""); 2819 printk("%sLAN", i ? "," : "");
2820 i++; 2820 i++;
2821 } 2821 }
2822 2822
2823 #if 0 2823 #if 0
2824 /* 2824 /*
2825 * This would probably evoke more questions than it's worth 2825 * This would probably evoke more questions than it's worth
2826 */ 2826 */
2827 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) { 2827 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2828 printk("%sLogBusAddr", i ? "," : ""); 2828 printk("%sLogBusAddr", i ? "," : "");
2829 i++; 2829 i++;
2830 } 2830 }
2831 #endif 2831 #endif
2832 2832
2833 printk("}\n"); 2833 printk("}\n");
2834 } 2834 }
2835 2835
2836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2837 /** 2837 /**
2838 * MakeIocReady - Get IOC to a READY state, using KickStart if needed. 2838 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2839 * @ioc: Pointer to MPT_ADAPTER structure 2839 * @ioc: Pointer to MPT_ADAPTER structure
2840 * @force: Force hard KickStart of IOC 2840 * @force: Force hard KickStart of IOC
2841 * @sleepFlag: Specifies whether the process can sleep 2841 * @sleepFlag: Specifies whether the process can sleep
2842 * 2842 *
2843 * Returns: 2843 * Returns:
2844 * 1 - DIAG reset and READY 2844 * 1 - DIAG reset and READY
2845 * 0 - READY initially OR soft reset and READY 2845 * 0 - READY initially OR soft reset and READY
2846 * -1 - Any failure on KickStart 2846 * -1 - Any failure on KickStart
2847 * -2 - Msg Unit Reset Failed 2847 * -2 - Msg Unit Reset Failed
2848 * -3 - IO Unit Reset Failed 2848 * -3 - IO Unit Reset Failed
2849 * -4 - IOC owned by a PEER 2849 * -4 - IOC owned by a PEER
2850 */ 2850 */
2851 static int 2851 static int
2852 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) 2852 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2853 { 2853 {
2854 u32 ioc_state; 2854 u32 ioc_state;
2855 int statefault = 0; 2855 int statefault = 0;
2856 int cntdn; 2856 int cntdn;
2857 int hard_reset_done = 0; 2857 int hard_reset_done = 0;
2858 int r; 2858 int r;
2859 int ii; 2859 int ii;
2860 int whoinit; 2860 int whoinit;
2861 2861
2862 /* Get current [raw] IOC state */ 2862 /* Get current [raw] IOC state */
2863 ioc_state = mpt_GetIocState(ioc, 0); 2863 ioc_state = mpt_GetIocState(ioc, 0);
2864 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state)); 2864 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2865 2865
2866 /* 2866 /*
2867 * Check to see if IOC got left/stuck in doorbell handshake 2867 * Check to see if IOC got left/stuck in doorbell handshake
2868 * grip of death. If so, hard reset the IOC. 2868 * grip of death. If so, hard reset the IOC.
2869 */ 2869 */
2870 if (ioc_state & MPI_DOORBELL_ACTIVE) { 2870 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2871 statefault = 1; 2871 statefault = 1;
2872 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n", 2872 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2873 ioc->name); 2873 ioc->name);
2874 } 2874 }
2875 2875
2876 /* Is it already READY? */ 2876 /* Is it already READY? */
2877 if (!statefault && 2877 if (!statefault &&
2878 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) { 2878 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2879 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2879 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2880 "IOC is in READY state\n", ioc->name)); 2880 "IOC is in READY state\n", ioc->name));
2881 return 0; 2881 return 0;
2882 } 2882 }
2883 2883
2884 /* 2884 /*
2885 * Check to see if IOC is in FAULT state. 2885 * Check to see if IOC is in FAULT state.
2886 */ 2886 */
2887 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 2887 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2888 statefault = 2; 2888 statefault = 2;
2889 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n", 2889 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2890 ioc->name); 2890 ioc->name);
2891 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n", 2891 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2892 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK); 2892 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2893 } 2893 }
2894 2894
2895 /* 2895 /*
2896 * Hmmm... Did it get left operational? 2896 * Hmmm... Did it get left operational?
2897 */ 2897 */
2898 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) { 2898 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2899 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n", 2899 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2900 ioc->name)); 2900 ioc->name));
2901 2901
2902 /* Check WhoInit. 2902 /* Check WhoInit.
2903 * If PCI Peer, exit. 2903 * If PCI Peer, exit.
2904 * Else, if no fault conditions are present, issue a MessageUnitReset 2904 * Else, if no fault conditions are present, issue a MessageUnitReset
2905 * Else, fall through to KickStart case 2905 * Else, fall through to KickStart case
2906 */ 2906 */
2907 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT; 2907 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2908 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2908 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2909 "whoinit 0x%x statefault %d force %d\n", 2909 "whoinit 0x%x statefault %d force %d\n",
2910 ioc->name, whoinit, statefault, force)); 2910 ioc->name, whoinit, statefault, force));
2911 if (whoinit == MPI_WHOINIT_PCI_PEER) 2911 if (whoinit == MPI_WHOINIT_PCI_PEER)
2912 return -4; 2912 return -4;
2913 else { 2913 else {
2914 if ((statefault == 0 ) && (force == 0)) { 2914 if ((statefault == 0 ) && (force == 0)) {
2915 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0) 2915 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2916 return 0; 2916 return 0;
2917 } 2917 }
2918 statefault = 3; 2918 statefault = 3;
2919 } 2919 }
2920 } 2920 }
2921 2921
2922 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag); 2922 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2923 if (hard_reset_done < 0) 2923 if (hard_reset_done < 0)
2924 return -1; 2924 return -1;
2925 2925
2926 /* 2926 /*
2927 * Loop here waiting for IOC to come READY. 2927 * Loop here waiting for IOC to come READY.
2928 */ 2928 */
2929 ii = 0; 2929 ii = 0;
2930 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */ 2930 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2931 2931
2932 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { 2932 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2933 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) { 2933 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2934 /* 2934 /*
2935 * BIOS or previous driver load left IOC in OP state. 2935 * BIOS or previous driver load left IOC in OP state.
2936 * Reset messaging FIFOs. 2936 * Reset messaging FIFOs.
2937 */ 2937 */
2938 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) { 2938 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2939 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name); 2939 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2940 return -2; 2940 return -2;
2941 } 2941 }
2942 } else if (ioc_state == MPI_IOC_STATE_RESET) { 2942 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2943 /* 2943 /*
2944 * Something is wrong. Try to get IOC back 2944 * Something is wrong. Try to get IOC back
2945 * to a known state. 2945 * to a known state.
2946 */ 2946 */
2947 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) { 2947 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2948 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name); 2948 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2949 return -3; 2949 return -3;
2950 } 2950 }
2951 } 2951 }
2952 2952
2953 ii++; cntdn--; 2953 ii++; cntdn--;
2954 if (!cntdn) { 2954 if (!cntdn) {
2955 printk(MYIOC_s_ERR_FMT 2955 printk(MYIOC_s_ERR_FMT
2956 "Wait IOC_READY state (0x%x) timeout(%d)!\n", 2956 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2957 ioc->name, ioc_state, (int)((ii+5)/HZ)); 2957 ioc->name, ioc_state, (int)((ii+5)/HZ));
2958 return -ETIME; 2958 return -ETIME;
2959 } 2959 }
2960 2960
2961 if (sleepFlag == CAN_SLEEP) { 2961 if (sleepFlag == CAN_SLEEP) {
2962 msleep(1); 2962 msleep(1);
2963 } else { 2963 } else {
2964 mdelay (1); /* 1 msec delay */ 2964 mdelay (1); /* 1 msec delay */
2965 } 2965 }
2966 2966
2967 } 2967 }
2968 2968
2969 if (statefault < 3) { 2969 if (statefault < 3) {
2970 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name, 2970 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
2971 statefault == 1 ? "stuck handshake" : "IOC FAULT"); 2971 statefault == 1 ? "stuck handshake" : "IOC FAULT");
2972 } 2972 }
2973 2973
2974 return hard_reset_done; 2974 return hard_reset_done;
2975 } 2975 }
2976 2976
2977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2978 /** 2978 /**
2979 * mpt_GetIocState - Get the current state of a MPT adapter. 2979 * mpt_GetIocState - Get the current state of a MPT adapter.
2980 * @ioc: Pointer to MPT_ADAPTER structure 2980 * @ioc: Pointer to MPT_ADAPTER structure
2981 * @cooked: Request raw or cooked IOC state 2981 * @cooked: Request raw or cooked IOC state
2982 * 2982 *
2983 * Returns all IOC Doorbell register bits if cooked==0, else just the 2983 * Returns all IOC Doorbell register bits if cooked==0, else just the
2984 * Doorbell bits in MPI_IOC_STATE_MASK. 2984 * Doorbell bits in MPI_IOC_STATE_MASK.
2985 */ 2985 */
2986 u32 2986 u32
2987 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked) 2987 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2988 { 2988 {
2989 u32 s, sc; 2989 u32 s, sc;
2990 2990
2991 /* Get! */ 2991 /* Get! */
2992 s = CHIPREG_READ32(&ioc->chip->Doorbell); 2992 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2993 sc = s & MPI_IOC_STATE_MASK; 2993 sc = s & MPI_IOC_STATE_MASK;
2994 2994
2995 /* Save! */ 2995 /* Save! */
2996 ioc->last_state = sc; 2996 ioc->last_state = sc;
2997 2997
2998 return cooked ? sc : s; 2998 return cooked ? sc : s;
2999 } 2999 }
3000 3000
3001 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3001 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3002 /** 3002 /**
3003 * GetIocFacts - Send IOCFacts request to MPT adapter. 3003 * GetIocFacts - Send IOCFacts request to MPT adapter.
3004 * @ioc: Pointer to MPT_ADAPTER structure 3004 * @ioc: Pointer to MPT_ADAPTER structure
3005 * @sleepFlag: Specifies whether the process can sleep 3005 * @sleepFlag: Specifies whether the process can sleep
3006 * @reason: If recovery, only update facts. 3006 * @reason: If recovery, only update facts.
3007 * 3007 *
3008 * Returns 0 for success, non-zero for failure. 3008 * Returns 0 for success, non-zero for failure.
3009 */ 3009 */
3010 static int 3010 static int
3011 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) 3011 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3012 { 3012 {
3013 IOCFacts_t get_facts; 3013 IOCFacts_t get_facts;
3014 IOCFactsReply_t *facts; 3014 IOCFactsReply_t *facts;
3015 int r; 3015 int r;
3016 int req_sz; 3016 int req_sz;
3017 int reply_sz; 3017 int reply_sz;
3018 int sz; 3018 int sz;
3019 u32 status, vv; 3019 u32 status, vv;
3020 u8 shiftFactor=1; 3020 u8 shiftFactor=1;
3021 3021
3022 /* IOC *must* NOT be in RESET state! */ 3022 /* IOC *must* NOT be in RESET state! */
3023 if (ioc->last_state == MPI_IOC_STATE_RESET) { 3023 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3024 printk(KERN_ERR MYNAM 3024 printk(KERN_ERR MYNAM
3025 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n", 3025 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3026 ioc->name, ioc->last_state); 3026 ioc->name, ioc->last_state);
3027 return -44; 3027 return -44;
3028 } 3028 }
3029 3029
3030 facts = &ioc->facts; 3030 facts = &ioc->facts;
3031 3031
3032 /* Destination (reply area)... */ 3032 /* Destination (reply area)... */
3033 reply_sz = sizeof(*facts); 3033 reply_sz = sizeof(*facts);
3034 memset(facts, 0, reply_sz); 3034 memset(facts, 0, reply_sz);
3035 3035
3036 /* Request area (get_facts on the stack right now!) */ 3036 /* Request area (get_facts on the stack right now!) */
3037 req_sz = sizeof(get_facts); 3037 req_sz = sizeof(get_facts);
3038 memset(&get_facts, 0, req_sz); 3038 memset(&get_facts, 0, req_sz);
3039 3039
3040 get_facts.Function = MPI_FUNCTION_IOC_FACTS; 3040 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3041 /* Assert: All other get_facts fields are zero! */ 3041 /* Assert: All other get_facts fields are zero! */
3042 3042
3043 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3043 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3044 "Sending get IocFacts request req_sz=%d reply_sz=%d\n", 3044 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3045 ioc->name, req_sz, reply_sz)); 3045 ioc->name, req_sz, reply_sz));
3046 3046
3047 /* No non-zero fields in the get_facts request are greater than 3047 /* No non-zero fields in the get_facts request are greater than
3048 * 1 byte in size, so we can just fire it off as is. 3048 * 1 byte in size, so we can just fire it off as is.
3049 */ 3049 */
3050 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts, 3050 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3051 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag); 3051 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3052 if (r != 0) 3052 if (r != 0)
3053 return r; 3053 return r;
3054 3054
3055 /* 3055 /*
3056 * Now byte swap (GRRR) the necessary fields before any further 3056 * Now byte swap (GRRR) the necessary fields before any further
3057 * inspection of reply contents. 3057 * inspection of reply contents.
3058 * 3058 *
3059 * But need to do some sanity checks on MsgLength (byte) field 3059 * But need to do some sanity checks on MsgLength (byte) field
3060 * to make sure we don't zero IOC's req_sz! 3060 * to make sure we don't zero IOC's req_sz!
3061 */ 3061 */
3062 /* Did we get a valid reply? */ 3062 /* Did we get a valid reply? */
3063 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) { 3063 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3064 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 3064 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3065 /* 3065 /*
3066 * If not been here, done that, save off first WhoInit value 3066 * If not been here, done that, save off first WhoInit value
3067 */ 3067 */
3068 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN) 3068 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3069 ioc->FirstWhoInit = facts->WhoInit; 3069 ioc->FirstWhoInit = facts->WhoInit;
3070 } 3070 }
3071 3071
3072 facts->MsgVersion = le16_to_cpu(facts->MsgVersion); 3072 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3073 facts->MsgContext = le32_to_cpu(facts->MsgContext); 3073 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3074 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions); 3074 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3075 facts->IOCStatus = le16_to_cpu(facts->IOCStatus); 3075 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3076 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo); 3076 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3077 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK; 3077 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3078 /* CHECKME! IOCStatus, IOCLogInfo */ 3078 /* CHECKME! IOCStatus, IOCLogInfo */
3079 3079
3080 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth); 3080 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3081 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize); 3081 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3082 3082
3083 /* 3083 /*
3084 * FC f/w version changed between 1.1 and 1.2 3084 * FC f/w version changed between 1.1 and 1.2
3085 * Old: u16{Major(4),Minor(4),SubMinor(8)} 3085 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3086 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)} 3086 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3087 */ 3087 */
3088 if (facts->MsgVersion < MPI_VERSION_01_02) { 3088 if (facts->MsgVersion < MPI_VERSION_01_02) {
3089 /* 3089 /*
3090 * Handle old FC f/w style, convert to new... 3090 * Handle old FC f/w style, convert to new...
3091 */ 3091 */
3092 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion); 3092 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3093 facts->FWVersion.Word = 3093 facts->FWVersion.Word =
3094 ((oldv<<12) & 0xFF000000) | 3094 ((oldv<<12) & 0xFF000000) |
3095 ((oldv<<8) & 0x000FFF00); 3095 ((oldv<<8) & 0x000FFF00);
3096 } else 3096 } else
3097 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); 3097 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3098 3098
3099 facts->ProductID = le16_to_cpu(facts->ProductID); 3099 facts->ProductID = le16_to_cpu(facts->ProductID);
3100 3100
3101 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 3101 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3102 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) 3102 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3103 ioc->ir_firmware = 1; 3103 ioc->ir_firmware = 1;
3104 3104
3105 facts->CurrentHostMfaHighAddr = 3105 facts->CurrentHostMfaHighAddr =
3106 le32_to_cpu(facts->CurrentHostMfaHighAddr); 3106 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3107 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); 3107 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3108 facts->CurrentSenseBufferHighAddr = 3108 facts->CurrentSenseBufferHighAddr =
3109 le32_to_cpu(facts->CurrentSenseBufferHighAddr); 3109 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3110 facts->CurReplyFrameSize = 3110 facts->CurReplyFrameSize =
3111 le16_to_cpu(facts->CurReplyFrameSize); 3111 le16_to_cpu(facts->CurReplyFrameSize);
3112 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities); 3112 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3113 3113
3114 /* 3114 /*
3115 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx 3115 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3116 * Older MPI-1.00.xx struct had 13 dwords, and enlarged 3116 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3117 * to 14 in MPI-1.01.0x. 3117 * to 14 in MPI-1.01.0x.
3118 */ 3118 */
3119 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 && 3119 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3120 facts->MsgVersion > MPI_VERSION_01_00) { 3120 facts->MsgVersion > MPI_VERSION_01_00) {
3121 facts->FWImageSize = le32_to_cpu(facts->FWImageSize); 3121 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3122 } 3122 }
3123 3123
3124 sz = facts->FWImageSize; 3124 sz = facts->FWImageSize;
3125 if ( sz & 0x01 ) 3125 if ( sz & 0x01 )
3126 sz += 1; 3126 sz += 1;
3127 if ( sz & 0x02 ) 3127 if ( sz & 0x02 )
3128 sz += 2; 3128 sz += 2;
3129 facts->FWImageSize = sz; 3129 facts->FWImageSize = sz;
3130 3130
3131 if (!facts->RequestFrameSize) { 3131 if (!facts->RequestFrameSize) {
3132 /* Something is wrong! */ 3132 /* Something is wrong! */
3133 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n", 3133 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3134 ioc->name); 3134 ioc->name);
3135 return -55; 3135 return -55;
3136 } 3136 }
3137 3137
3138 r = sz = facts->BlockSize; 3138 r = sz = facts->BlockSize;
3139 vv = ((63 / (sz * 4)) + 1) & 0x03; 3139 vv = ((63 / (sz * 4)) + 1) & 0x03;
3140 ioc->NB_for_64_byte_frame = vv; 3140 ioc->NB_for_64_byte_frame = vv;
3141 while ( sz ) 3141 while ( sz )
3142 { 3142 {
3143 shiftFactor++; 3143 shiftFactor++;
3144 sz = sz >> 1; 3144 sz = sz >> 1;
3145 } 3145 }
3146 ioc->NBShiftFactor = shiftFactor; 3146 ioc->NBShiftFactor = shiftFactor;
3147 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3147 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3148 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n", 3148 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3149 ioc->name, vv, shiftFactor, r)); 3149 ioc->name, vv, shiftFactor, r));
3150 3150
3151 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 3151 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3152 /* 3152 /*
3153 * Set values for this IOC's request & reply frame sizes, 3153 * Set values for this IOC's request & reply frame sizes,
3154 * and request & reply queue depths... 3154 * and request & reply queue depths...
3155 */ 3155 */
3156 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4); 3156 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3157 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits); 3157 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3158 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 3158 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3159 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth); 3159 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3160 3160
3161 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n", 3161 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3162 ioc->name, ioc->reply_sz, ioc->reply_depth)); 3162 ioc->name, ioc->reply_sz, ioc->reply_depth));
3163 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n", 3163 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3164 ioc->name, ioc->req_sz, ioc->req_depth)); 3164 ioc->name, ioc->req_sz, ioc->req_depth));
3165 3165
3166 /* Get port facts! */ 3166 /* Get port facts! */
3167 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 ) 3167 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3168 return r; 3168 return r;
3169 } 3169 }
3170 } else { 3170 } else {
3171 printk(MYIOC_s_ERR_FMT 3171 printk(MYIOC_s_ERR_FMT
3172 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n", 3172 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3173 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t, 3173 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3174 RequestFrameSize)/sizeof(u32))); 3174 RequestFrameSize)/sizeof(u32)));
3175 return -66; 3175 return -66;
3176 } 3176 }
3177 3177
3178 return 0; 3178 return 0;
3179 } 3179 }
3180 3180
3181 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3181 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3182 /** 3182 /**
3183 * GetPortFacts - Send PortFacts request to MPT adapter. 3183 * GetPortFacts - Send PortFacts request to MPT adapter.
3184 * @ioc: Pointer to MPT_ADAPTER structure 3184 * @ioc: Pointer to MPT_ADAPTER structure
3185 * @portnum: Port number 3185 * @portnum: Port number
3186 * @sleepFlag: Specifies whether the process can sleep 3186 * @sleepFlag: Specifies whether the process can sleep
3187 * 3187 *
3188 * Returns 0 for success, non-zero for failure. 3188 * Returns 0 for success, non-zero for failure.
3189 */ 3189 */
3190 static int 3190 static int
3191 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) 3191 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3192 { 3192 {
3193 PortFacts_t get_pfacts; 3193 PortFacts_t get_pfacts;
3194 PortFactsReply_t *pfacts; 3194 PortFactsReply_t *pfacts;
3195 int ii; 3195 int ii;
3196 int req_sz; 3196 int req_sz;
3197 int reply_sz; 3197 int reply_sz;
3198 int max_id; 3198 int max_id;
3199 3199
3200 /* IOC *must* NOT be in RESET state! */ 3200 /* IOC *must* NOT be in RESET state! */
3201 if (ioc->last_state == MPI_IOC_STATE_RESET) { 3201 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3202 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n", 3202 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3203 ioc->name, ioc->last_state ); 3203 ioc->name, ioc->last_state );
3204 return -4; 3204 return -4;
3205 } 3205 }
3206 3206
3207 pfacts = &ioc->pfacts[portnum]; 3207 pfacts = &ioc->pfacts[portnum];
3208 3208
3209 /* Destination (reply area)... */ 3209 /* Destination (reply area)... */
3210 reply_sz = sizeof(*pfacts); 3210 reply_sz = sizeof(*pfacts);
3211 memset(pfacts, 0, reply_sz); 3211 memset(pfacts, 0, reply_sz);
3212 3212
3213 /* Request area (get_pfacts on the stack right now!) */ 3213 /* Request area (get_pfacts on the stack right now!) */
3214 req_sz = sizeof(get_pfacts); 3214 req_sz = sizeof(get_pfacts);
3215 memset(&get_pfacts, 0, req_sz); 3215 memset(&get_pfacts, 0, req_sz);
3216 3216
3217 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS; 3217 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3218 get_pfacts.PortNumber = portnum; 3218 get_pfacts.PortNumber = portnum;
3219 /* Assert: All other get_pfacts fields are zero! */ 3219 /* Assert: All other get_pfacts fields are zero! */
3220 3220
3221 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n", 3221 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3222 ioc->name, portnum)); 3222 ioc->name, portnum));
3223 3223
3224 /* No non-zero fields in the get_pfacts request are greater than 3224 /* No non-zero fields in the get_pfacts request are greater than
3225 * 1 byte in size, so we can just fire it off as is. 3225 * 1 byte in size, so we can just fire it off as is.
3226 */ 3226 */
3227 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts, 3227 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3228 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag); 3228 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3229 if (ii != 0) 3229 if (ii != 0)
3230 return ii; 3230 return ii;
3231 3231
3232 /* Did we get a valid reply? */ 3232 /* Did we get a valid reply? */
3233 3233
3234 /* Now byte swap the necessary fields in the response. */ 3234 /* Now byte swap the necessary fields in the response. */
3235 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext); 3235 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3236 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus); 3236 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3237 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo); 3237 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3238 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices); 3238 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3239 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID); 3239 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3240 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags); 3240 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3241 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers); 3241 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3242 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); 3242 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3243 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); 3243 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3244 3244
3245 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID : 3245 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3246 pfacts->MaxDevices; 3246 pfacts->MaxDevices;
3247 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id; 3247 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3248 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256; 3248 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3249 3249
3250 /* 3250 /*
3251 * Place all the devices on channels 3251 * Place all the devices on channels
3252 * 3252 *
3253 * (for debuging) 3253 * (for debuging)
3254 */ 3254 */
3255 if (mpt_channel_mapping) { 3255 if (mpt_channel_mapping) {
3256 ioc->devices_per_bus = 1; 3256 ioc->devices_per_bus = 1;
3257 ioc->number_of_buses = (max_id > 255) ? 255 : max_id; 3257 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3258 } 3258 }
3259 3259
3260 return 0; 3260 return 0;
3261 } 3261 }
3262 3262
3263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3264 /** 3264 /**
3265 * SendIocInit - Send IOCInit request to MPT adapter. 3265 * SendIocInit - Send IOCInit request to MPT adapter.
3266 * @ioc: Pointer to MPT_ADAPTER structure 3266 * @ioc: Pointer to MPT_ADAPTER structure
3267 * @sleepFlag: Specifies whether the process can sleep 3267 * @sleepFlag: Specifies whether the process can sleep
3268 * 3268 *
3269 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state. 3269 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3270 * 3270 *
3271 * Returns 0 for success, non-zero for failure. 3271 * Returns 0 for success, non-zero for failure.
3272 */ 3272 */
3273 static int 3273 static int
3274 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) 3274 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3275 { 3275 {
3276 IOCInit_t ioc_init; 3276 IOCInit_t ioc_init;
3277 MPIDefaultReply_t init_reply; 3277 MPIDefaultReply_t init_reply;
3278 u32 state; 3278 u32 state;
3279 int r; 3279 int r;
3280 int count; 3280 int count;
3281 int cntdn; 3281 int cntdn;
3282 3282
3283 memset(&ioc_init, 0, sizeof(ioc_init)); 3283 memset(&ioc_init, 0, sizeof(ioc_init));
3284 memset(&init_reply, 0, sizeof(init_reply)); 3284 memset(&init_reply, 0, sizeof(init_reply));
3285 3285
3286 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER; 3286 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3287 ioc_init.Function = MPI_FUNCTION_IOC_INIT; 3287 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3288 3288
3289 /* If we are in a recovery mode and we uploaded the FW image, 3289 /* If we are in a recovery mode and we uploaded the FW image,
3290 * then this pointer is not NULL. Skip the upload a second time. 3290 * then this pointer is not NULL. Skip the upload a second time.
3291 * Set this flag if cached_fw set for either IOC. 3291 * Set this flag if cached_fw set for either IOC.
3292 */ 3292 */
3293 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) 3293 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3294 ioc->upload_fw = 1; 3294 ioc->upload_fw = 1;
3295 else 3295 else
3296 ioc->upload_fw = 0; 3296 ioc->upload_fw = 0;
3297 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n", 3297 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3298 ioc->name, ioc->upload_fw, ioc->facts.Flags)); 3298 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3299 3299
3300 ioc_init.MaxDevices = (U8)ioc->devices_per_bus; 3300 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3301 ioc_init.MaxBuses = (U8)ioc->number_of_buses; 3301 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3302 3302
3303 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n", 3303 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3304 ioc->name, ioc->facts.MsgVersion)); 3304 ioc->name, ioc->facts.MsgVersion));
3305 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { 3305 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3306 // set MsgVersion and HeaderVersion host driver was built with 3306 // set MsgVersion and HeaderVersion host driver was built with
3307 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION); 3307 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3308 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION); 3308 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3309 3309
3310 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) { 3310 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3311 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE; 3311 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3312 } else if(mpt_host_page_alloc(ioc, &ioc_init)) 3312 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3313 return -99; 3313 return -99;
3314 } 3314 }
3315 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ 3315 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3316 3316
3317 if (ioc->sg_addr_size == sizeof(u64)) { 3317 if (ioc->sg_addr_size == sizeof(u64)) {
3318 /* Save the upper 32-bits of the request 3318 /* Save the upper 32-bits of the request
3319 * (reply) and sense buffers. 3319 * (reply) and sense buffers.
3320 */ 3320 */
3321 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32)); 3321 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3322 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32)); 3322 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3323 } else { 3323 } else {
3324 /* Force 32-bit addressing */ 3324 /* Force 32-bit addressing */
3325 ioc_init.HostMfaHighAddr = cpu_to_le32(0); 3325 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3326 ioc_init.SenseBufferHighAddr = cpu_to_le32(0); 3326 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3327 } 3327 }
3328 3328
3329 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr; 3329 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3330 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr; 3330 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3331 ioc->facts.MaxDevices = ioc_init.MaxDevices; 3331 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3332 ioc->facts.MaxBuses = ioc_init.MaxBuses; 3332 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3333 3333
3334 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n", 3334 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3335 ioc->name, &ioc_init)); 3335 ioc->name, &ioc_init));
3336 3336
3337 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init, 3337 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3338 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag); 3338 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3339 if (r != 0) { 3339 if (r != 0) {
3340 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r); 3340 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3341 return r; 3341 return r;
3342 } 3342 }
3343 3343
3344 /* No need to byte swap the multibyte fields in the reply 3344 /* No need to byte swap the multibyte fields in the reply
3345 * since we don't even look at its contents. 3345 * since we don't even look at its contents.
3346 */ 3346 */
3347 3347
3348 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n", 3348 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3349 ioc->name, &ioc_init)); 3349 ioc->name, &ioc_init));
3350 3350
3351 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) { 3351 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3352 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r); 3352 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3353 return r; 3353 return r;
3354 } 3354 }
3355 3355
3356 /* YIKES! SUPER IMPORTANT!!! 3356 /* YIKES! SUPER IMPORTANT!!!
3357 * Poll IocState until _OPERATIONAL while IOC is doing 3357 * Poll IocState until _OPERATIONAL while IOC is doing
3358 * LoopInit and TargetDiscovery! 3358 * LoopInit and TargetDiscovery!
3359 */ 3359 */
3360 count = 0; 3360 count = 0;
3361 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */ 3361 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3362 state = mpt_GetIocState(ioc, 1); 3362 state = mpt_GetIocState(ioc, 1);
3363 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) { 3363 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3364 if (sleepFlag == CAN_SLEEP) { 3364 if (sleepFlag == CAN_SLEEP) {
3365 msleep(1); 3365 msleep(1);
3366 } else { 3366 } else {
3367 mdelay(1); 3367 mdelay(1);
3368 } 3368 }
3369 3369
3370 if (!cntdn) { 3370 if (!cntdn) {
3371 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n", 3371 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3372 ioc->name, (int)((count+5)/HZ)); 3372 ioc->name, (int)((count+5)/HZ));
3373 return -9; 3373 return -9;
3374 } 3374 }
3375 3375
3376 state = mpt_GetIocState(ioc, 1); 3376 state = mpt_GetIocState(ioc, 1);
3377 count++; 3377 count++;
3378 } 3378 }
3379 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n", 3379 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3380 ioc->name, count)); 3380 ioc->name, count));
3381 3381
3382 ioc->aen_event_read_flag=0; 3382 ioc->aen_event_read_flag=0;
3383 return r; 3383 return r;
3384 } 3384 }
3385 3385
3386 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3386 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3387 /** 3387 /**
3388 * SendPortEnable - Send PortEnable request to MPT adapter port. 3388 * SendPortEnable - Send PortEnable request to MPT adapter port.
3389 * @ioc: Pointer to MPT_ADAPTER structure 3389 * @ioc: Pointer to MPT_ADAPTER structure
3390 * @portnum: Port number to enable 3390 * @portnum: Port number to enable
3391 * @sleepFlag: Specifies whether the process can sleep 3391 * @sleepFlag: Specifies whether the process can sleep
3392 * 3392 *
3393 * Send PortEnable to bring IOC to OPERATIONAL state. 3393 * Send PortEnable to bring IOC to OPERATIONAL state.
3394 * 3394 *
3395 * Returns 0 for success, non-zero for failure. 3395 * Returns 0 for success, non-zero for failure.
3396 */ 3396 */
3397 static int 3397 static int
3398 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) 3398 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3399 { 3399 {
3400 PortEnable_t port_enable; 3400 PortEnable_t port_enable;
3401 MPIDefaultReply_t reply_buf; 3401 MPIDefaultReply_t reply_buf;
3402 int rc; 3402 int rc;
3403 int req_sz; 3403 int req_sz;
3404 int reply_sz; 3404 int reply_sz;
3405 3405
3406 /* Destination... */ 3406 /* Destination... */
3407 reply_sz = sizeof(MPIDefaultReply_t); 3407 reply_sz = sizeof(MPIDefaultReply_t);
3408 memset(&reply_buf, 0, reply_sz); 3408 memset(&reply_buf, 0, reply_sz);
3409 3409
3410 req_sz = sizeof(PortEnable_t); 3410 req_sz = sizeof(PortEnable_t);
3411 memset(&port_enable, 0, req_sz); 3411 memset(&port_enable, 0, req_sz);
3412 3412
3413 port_enable.Function = MPI_FUNCTION_PORT_ENABLE; 3413 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3414 port_enable.PortNumber = portnum; 3414 port_enable.PortNumber = portnum;
3415 /* port_enable.ChainOffset = 0; */ 3415 /* port_enable.ChainOffset = 0; */
3416 /* port_enable.MsgFlags = 0; */ 3416 /* port_enable.MsgFlags = 0; */
3417 /* port_enable.MsgContext = 0; */ 3417 /* port_enable.MsgContext = 0; */
3418 3418
3419 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n", 3419 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3420 ioc->name, portnum, &port_enable)); 3420 ioc->name, portnum, &port_enable));
3421 3421
3422 /* RAID FW may take a long time to enable 3422 /* RAID FW may take a long time to enable
3423 */ 3423 */
3424 if (ioc->ir_firmware || ioc->bus_type == SAS) { 3424 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3425 rc = mpt_handshake_req_reply_wait(ioc, req_sz, 3425 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3426 (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 3426 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3427 300 /*seconds*/, sleepFlag); 3427 300 /*seconds*/, sleepFlag);
3428 } else { 3428 } else {
3429 rc = mpt_handshake_req_reply_wait(ioc, req_sz, 3429 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3430 (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 3430 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3431 30 /*seconds*/, sleepFlag); 3431 30 /*seconds*/, sleepFlag);
3432 } 3432 }
3433 return rc; 3433 return rc;
3434 } 3434 }
3435 3435
3436 /** 3436 /**
3437 * mpt_alloc_fw_memory - allocate firmware memory 3437 * mpt_alloc_fw_memory - allocate firmware memory
3438 * @ioc: Pointer to MPT_ADAPTER structure 3438 * @ioc: Pointer to MPT_ADAPTER structure
3439 * @size: total FW bytes 3439 * @size: total FW bytes
3440 * 3440 *
3441 * If memory has already been allocated, the same (cached) value 3441 * If memory has already been allocated, the same (cached) value
3442 * is returned. 3442 * is returned.
3443 * 3443 *
3444 * Return 0 if successfull, or non-zero for failure 3444 * Return 0 if successfull, or non-zero for failure
3445 **/ 3445 **/
3446 int 3446 int
3447 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) 3447 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3448 { 3448 {
3449 int rc; 3449 int rc;
3450 3450
3451 if (ioc->cached_fw) { 3451 if (ioc->cached_fw) {
3452 rc = 0; /* use already allocated memory */ 3452 rc = 0; /* use already allocated memory */
3453 goto out; 3453 goto out;
3454 } 3454 }
3455 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { 3455 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3456 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */ 3456 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3457 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma; 3457 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3458 rc = 0; 3458 rc = 0;
3459 goto out; 3459 goto out;
3460 } 3460 }
3461 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma); 3461 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3462 if (!ioc->cached_fw) { 3462 if (!ioc->cached_fw) {
3463 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n", 3463 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3464 ioc->name); 3464 ioc->name);
3465 rc = -1; 3465 rc = -1;
3466 } else { 3466 } else {
3467 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n", 3467 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3468 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size)); 3468 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3469 ioc->alloc_total += size; 3469 ioc->alloc_total += size;
3470 rc = 0; 3470 rc = 0;
3471 } 3471 }
3472 out: 3472 out:
3473 return rc; 3473 return rc;
3474 } 3474 }
3475 3475
3476 /** 3476 /**
3477 * mpt_free_fw_memory - free firmware memory 3477 * mpt_free_fw_memory - free firmware memory
3478 * @ioc: Pointer to MPT_ADAPTER structure 3478 * @ioc: Pointer to MPT_ADAPTER structure
3479 * 3479 *
3480 * If alt_img is NULL, delete from ioc structure. 3480 * If alt_img is NULL, delete from ioc structure.
3481 * Else, delete a secondary image in same format. 3481 * Else, delete a secondary image in same format.
3482 **/ 3482 **/
3483 void 3483 void
3484 mpt_free_fw_memory(MPT_ADAPTER *ioc) 3484 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3485 { 3485 {
3486 int sz; 3486 int sz;
3487 3487
3488 if (!ioc->cached_fw) 3488 if (!ioc->cached_fw)
3489 return; 3489 return;
3490 3490
3491 sz = ioc->facts.FWImageSize; 3491 sz = ioc->facts.FWImageSize;
3492 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n", 3492 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3493 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 3493 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3494 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma); 3494 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3495 ioc->alloc_total -= sz; 3495 ioc->alloc_total -= sz;
3496 ioc->cached_fw = NULL; 3496 ioc->cached_fw = NULL;
3497 } 3497 }
3498 3498
3499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3500 /** 3500 /**
3501 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port. 3501 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3502 * @ioc: Pointer to MPT_ADAPTER structure 3502 * @ioc: Pointer to MPT_ADAPTER structure
3503 * @sleepFlag: Specifies whether the process can sleep 3503 * @sleepFlag: Specifies whether the process can sleep
3504 * 3504 *
3505 * Returns 0 for success, >0 for handshake failure 3505 * Returns 0 for success, >0 for handshake failure
3506 * <0 for fw upload failure. 3506 * <0 for fw upload failure.
3507 * 3507 *
3508 * Remark: If bound IOC and a successful FWUpload was performed 3508 * Remark: If bound IOC and a successful FWUpload was performed
3509 * on the bound IOC, the second image is discarded 3509 * on the bound IOC, the second image is discarded
3510 * and memory is free'd. Both channels must upload to prevent 3510 * and memory is free'd. Both channels must upload to prevent
3511 * IOC from running in degraded mode. 3511 * IOC from running in degraded mode.
3512 */ 3512 */
3513 static int 3513 static int
3514 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) 3514 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3515 { 3515 {
3516 u8 reply[sizeof(FWUploadReply_t)]; 3516 u8 reply[sizeof(FWUploadReply_t)];
3517 FWUpload_t *prequest; 3517 FWUpload_t *prequest;
3518 FWUploadReply_t *preply; 3518 FWUploadReply_t *preply;
3519 FWUploadTCSGE_t *ptcsge; 3519 FWUploadTCSGE_t *ptcsge;
3520 u32 flagsLength; 3520 u32 flagsLength;
3521 int ii, sz, reply_sz; 3521 int ii, sz, reply_sz;
3522 int cmdStatus; 3522 int cmdStatus;
3523 int request_size; 3523 int request_size;
3524 /* If the image size is 0, we are done. 3524 /* If the image size is 0, we are done.
3525 */ 3525 */
3526 if ((sz = ioc->facts.FWImageSize) == 0) 3526 if ((sz = ioc->facts.FWImageSize) == 0)
3527 return 0; 3527 return 0;
3528 3528
3529 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0) 3529 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3530 return -ENOMEM; 3530 return -ENOMEM;
3531 3531
3532 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n", 3532 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3533 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 3533 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3534 3534
3535 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) : 3535 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3536 kzalloc(ioc->req_sz, GFP_KERNEL); 3536 kzalloc(ioc->req_sz, GFP_KERNEL);
3537 if (!prequest) { 3537 if (!prequest) {
3538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed " 3538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3539 "while allocating memory \n", ioc->name)); 3539 "while allocating memory \n", ioc->name));
3540 mpt_free_fw_memory(ioc); 3540 mpt_free_fw_memory(ioc);
3541 return -ENOMEM; 3541 return -ENOMEM;
3542 } 3542 }
3543 3543
3544 preply = (FWUploadReply_t *)&reply; 3544 preply = (FWUploadReply_t *)&reply;
3545 3545
3546 reply_sz = sizeof(reply); 3546 reply_sz = sizeof(reply);
3547 memset(preply, 0, reply_sz); 3547 memset(preply, 0, reply_sz);
3548 3548
3549 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM; 3549 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3550 prequest->Function = MPI_FUNCTION_FW_UPLOAD; 3550 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3551 3551
3552 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL; 3552 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3553 ptcsge->DetailsLength = 12; 3553 ptcsge->DetailsLength = 12;
3554 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT; 3554 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3555 ptcsge->ImageSize = cpu_to_le32(sz); 3555 ptcsge->ImageSize = cpu_to_le32(sz);
3556 ptcsge++; 3556 ptcsge++;
3557 3557
3558 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz; 3558 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3559 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma); 3559 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3560 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) + 3560 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3561 ioc->SGE_size; 3561 ioc->SGE_size;
3562 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload " 3562 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3563 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest, 3563 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3564 ioc->facts.FWImageSize, request_size)); 3564 ioc->facts.FWImageSize, request_size));
3565 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest); 3565 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3566 3566
3567 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest, 3567 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3568 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag); 3568 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3569 3569
3570 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed " 3570 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3571 "rc=%x \n", ioc->name, ii)); 3571 "rc=%x \n", ioc->name, ii));
3572 3572
3573 cmdStatus = -EFAULT; 3573 cmdStatus = -EFAULT;
3574 if (ii == 0) { 3574 if (ii == 0) {
3575 /* Handshake transfer was complete and successful. 3575 /* Handshake transfer was complete and successful.
3576 * Check the Reply Frame. 3576 * Check the Reply Frame.
3577 */ 3577 */
3578 int status; 3578 int status;
3579 status = le16_to_cpu(preply->IOCStatus) & 3579 status = le16_to_cpu(preply->IOCStatus) &
3580 MPI_IOCSTATUS_MASK; 3580 MPI_IOCSTATUS_MASK;
3581 if (status == MPI_IOCSTATUS_SUCCESS && 3581 if (status == MPI_IOCSTATUS_SUCCESS &&
3582 ioc->facts.FWImageSize == 3582 ioc->facts.FWImageSize ==
3583 le32_to_cpu(preply->ActualImageSize)) 3583 le32_to_cpu(preply->ActualImageSize))
3584 cmdStatus = 0; 3584 cmdStatus = 0;
3585 } 3585 }
3586 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n", 3586 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3587 ioc->name, cmdStatus)); 3587 ioc->name, cmdStatus));
3588 3588
3589 3589
3590 if (cmdStatus) { 3590 if (cmdStatus) {
3591 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, " 3591 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3592 "freeing image \n", ioc->name)); 3592 "freeing image \n", ioc->name));
3593 mpt_free_fw_memory(ioc); 3593 mpt_free_fw_memory(ioc);
3594 } 3594 }
3595 kfree(prequest); 3595 kfree(prequest);
3596 3596
3597 return cmdStatus; 3597 return cmdStatus;
3598 } 3598 }
3599 3599
3600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3601 /** 3601 /**
3602 * mpt_downloadboot - DownloadBoot code 3602 * mpt_downloadboot - DownloadBoot code
3603 * @ioc: Pointer to MPT_ADAPTER structure 3603 * @ioc: Pointer to MPT_ADAPTER structure
3604 * @pFwHeader: Pointer to firmware header info 3604 * @pFwHeader: Pointer to firmware header info
3605 * @sleepFlag: Specifies whether the process can sleep 3605 * @sleepFlag: Specifies whether the process can sleep
3606 * 3606 *
3607 * FwDownloadBoot requires Programmed IO access. 3607 * FwDownloadBoot requires Programmed IO access.
3608 * 3608 *
3609 * Returns 0 for success 3609 * Returns 0 for success
3610 * -1 FW Image size is 0 3610 * -1 FW Image size is 0
3611 * -2 No valid cached_fw Pointer 3611 * -2 No valid cached_fw Pointer
3612 * <0 for fw upload failure. 3612 * <0 for fw upload failure.
3613 */ 3613 */
3614 static int 3614 static int
3615 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag) 3615 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3616 { 3616 {
3617 MpiExtImageHeader_t *pExtImage; 3617 MpiExtImageHeader_t *pExtImage;
3618 u32 fwSize; 3618 u32 fwSize;
3619 u32 diag0val; 3619 u32 diag0val;
3620 int count; 3620 int count;
3621 u32 *ptrFw; 3621 u32 *ptrFw;
3622 u32 diagRwData; 3622 u32 diagRwData;
3623 u32 nextImage; 3623 u32 nextImage;
3624 u32 load_addr; 3624 u32 load_addr;
3625 u32 ioc_state=0; 3625 u32 ioc_state=0;
3626 3626
3627 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n", 3627 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3628 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader)); 3628 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3629 3629
3630 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3630 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3631 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3631 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3632 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3632 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3633 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3633 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3634 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3634 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3635 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3635 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3636 3636
3637 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM)); 3637 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3638 3638
3639 /* wait 1 msec */ 3639 /* wait 1 msec */
3640 if (sleepFlag == CAN_SLEEP) { 3640 if (sleepFlag == CAN_SLEEP) {
3641 msleep(1); 3641 msleep(1);
3642 } else { 3642 } else {
3643 mdelay (1); 3643 mdelay (1);
3644 } 3644 }
3645 3645
3646 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3646 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3647 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER); 3647 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3648 3648
3649 for (count = 0; count < 30; count ++) { 3649 for (count = 0; count < 30; count ++) {
3650 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3650 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3651 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { 3651 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3652 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n", 3652 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3653 ioc->name, count)); 3653 ioc->name, count));
3654 break; 3654 break;
3655 } 3655 }
3656 /* wait .1 sec */ 3656 /* wait .1 sec */
3657 if (sleepFlag == CAN_SLEEP) { 3657 if (sleepFlag == CAN_SLEEP) {
3658 msleep (100); 3658 msleep (100);
3659 } else { 3659 } else {
3660 mdelay (100); 3660 mdelay (100);
3661 } 3661 }
3662 } 3662 }
3663 3663
3664 if ( count == 30 ) { 3664 if ( count == 30 ) {
3665 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! " 3665 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3666 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n", 3666 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3667 ioc->name, diag0val)); 3667 ioc->name, diag0val));
3668 return -3; 3668 return -3;
3669 } 3669 }
3670 3670
3671 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3671 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3672 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3672 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3673 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3673 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3674 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3674 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3675 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3675 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3676 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3676 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3677 3677
3678 /* Set the DiagRwEn and Disable ARM bits */ 3678 /* Set the DiagRwEn and Disable ARM bits */
3679 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM)); 3679 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3680 3680
3681 fwSize = (pFwHeader->ImageSize + 3)/4; 3681 fwSize = (pFwHeader->ImageSize + 3)/4;
3682 ptrFw = (u32 *) pFwHeader; 3682 ptrFw = (u32 *) pFwHeader;
3683 3683
3684 /* Write the LoadStartAddress to the DiagRw Address Register 3684 /* Write the LoadStartAddress to the DiagRw Address Register
3685 * using Programmed IO 3685 * using Programmed IO
3686 */ 3686 */
3687 if (ioc->errata_flag_1064) 3687 if (ioc->errata_flag_1064)
3688 pci_enable_io_access(ioc->pcidev); 3688 pci_enable_io_access(ioc->pcidev);
3689 3689
3690 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress); 3690 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3691 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n", 3691 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3692 ioc->name, pFwHeader->LoadStartAddress)); 3692 ioc->name, pFwHeader->LoadStartAddress));
3693 3693
3694 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n", 3694 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3695 ioc->name, fwSize*4, ptrFw)); 3695 ioc->name, fwSize*4, ptrFw));
3696 while (fwSize--) { 3696 while (fwSize--) {
3697 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++); 3697 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3698 } 3698 }
3699 3699
3700 nextImage = pFwHeader->NextImageHeaderOffset; 3700 nextImage = pFwHeader->NextImageHeaderOffset;
3701 while (nextImage) { 3701 while (nextImage) {
3702 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage); 3702 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3703 3703
3704 load_addr = pExtImage->LoadStartAddress; 3704 load_addr = pExtImage->LoadStartAddress;
3705 3705
3706 fwSize = (pExtImage->ImageSize + 3) >> 2; 3706 fwSize = (pExtImage->ImageSize + 3) >> 2;
3707 ptrFw = (u32 *)pExtImage; 3707 ptrFw = (u32 *)pExtImage;
3708 3708
3709 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n", 3709 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3710 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr)); 3710 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3711 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr); 3711 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3712 3712
3713 while (fwSize--) { 3713 while (fwSize--) {
3714 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++); 3714 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3715 } 3715 }
3716 nextImage = pExtImage->NextImageHeaderOffset; 3716 nextImage = pExtImage->NextImageHeaderOffset;
3717 } 3717 }
3718 3718
3719 /* Write the IopResetVectorRegAddr */ 3719 /* Write the IopResetVectorRegAddr */
3720 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr)); 3720 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3721 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr); 3721 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3722 3722
3723 /* Write the IopResetVectorValue */ 3723 /* Write the IopResetVectorValue */
3724 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue)); 3724 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3725 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue); 3725 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3726 3726
3727 /* Clear the internal flash bad bit - autoincrementing register, 3727 /* Clear the internal flash bad bit - autoincrementing register,
3728 * so must do two writes. 3728 * so must do two writes.
3729 */ 3729 */
3730 if (ioc->bus_type == SPI) { 3730 if (ioc->bus_type == SPI) {
3731 /* 3731 /*
3732 * 1030 and 1035 H/W errata, workaround to access 3732 * 1030 and 1035 H/W errata, workaround to access
3733 * the ClearFlashBadSignatureBit 3733 * the ClearFlashBadSignatureBit
3734 */ 3734 */
3735 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); 3735 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3736 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData); 3736 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3737 diagRwData |= 0x40000000; 3737 diagRwData |= 0x40000000;
3738 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); 3738 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3739 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData); 3739 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3740 3740
3741 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ { 3741 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3742 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3742 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3743 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | 3743 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3744 MPI_DIAG_CLEAR_FLASH_BAD_SIG); 3744 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3745 3745
3746 /* wait 1 msec */ 3746 /* wait 1 msec */
3747 if (sleepFlag == CAN_SLEEP) { 3747 if (sleepFlag == CAN_SLEEP) {
3748 msleep (1); 3748 msleep (1);
3749 } else { 3749 } else {
3750 mdelay (1); 3750 mdelay (1);
3751 } 3751 }
3752 } 3752 }
3753 3753
3754 if (ioc->errata_flag_1064) 3754 if (ioc->errata_flag_1064)
3755 pci_disable_io_access(ioc->pcidev); 3755 pci_disable_io_access(ioc->pcidev);
3756 3756
3757 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3757 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3758 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, " 3758 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3759 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n", 3759 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3760 ioc->name, diag0val)); 3760 ioc->name, diag0val));
3761 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE); 3761 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3762 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n", 3762 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3763 ioc->name, diag0val)); 3763 ioc->name, diag0val));
3764 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); 3764 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3765 3765
3766 /* Write 0xFF to reset the sequencer */ 3766 /* Write 0xFF to reset the sequencer */
3767 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3767 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3768 3768
3769 if (ioc->bus_type == SAS) { 3769 if (ioc->bus_type == SAS) {
3770 ioc_state = mpt_GetIocState(ioc, 0); 3770 ioc_state = mpt_GetIocState(ioc, 0);
3771 if ( (GetIocFacts(ioc, sleepFlag, 3771 if ( (GetIocFacts(ioc, sleepFlag,
3772 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) { 3772 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3773 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n", 3773 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3774 ioc->name, ioc_state)); 3774 ioc->name, ioc_state));
3775 return -EFAULT; 3775 return -EFAULT;
3776 } 3776 }
3777 } 3777 }
3778 3778
3779 for (count=0; count<HZ*20; count++) { 3779 for (count=0; count<HZ*20; count++) {
3780 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) { 3780 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3781 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3781 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3782 "downloadboot successful! (count=%d) IocState=%x\n", 3782 "downloadboot successful! (count=%d) IocState=%x\n",
3783 ioc->name, count, ioc_state)); 3783 ioc->name, count, ioc_state));
3784 if (ioc->bus_type == SAS) { 3784 if (ioc->bus_type == SAS) {
3785 return 0; 3785 return 0;
3786 } 3786 }
3787 if ((SendIocInit(ioc, sleepFlag)) != 0) { 3787 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3788 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3788 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3789 "downloadboot: SendIocInit failed\n", 3789 "downloadboot: SendIocInit failed\n",
3790 ioc->name)); 3790 ioc->name));
3791 return -EFAULT; 3791 return -EFAULT;
3792 } 3792 }
3793 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3793 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3794 "downloadboot: SendIocInit successful\n", 3794 "downloadboot: SendIocInit successful\n",
3795 ioc->name)); 3795 ioc->name));
3796 return 0; 3796 return 0;
3797 } 3797 }
3798 if (sleepFlag == CAN_SLEEP) { 3798 if (sleepFlag == CAN_SLEEP) {
3799 msleep (10); 3799 msleep (10);
3800 } else { 3800 } else {
3801 mdelay (10); 3801 mdelay (10);
3802 } 3802 }
3803 } 3803 }
3804 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3804 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3805 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state)); 3805 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3806 return -EFAULT; 3806 return -EFAULT;
3807 } 3807 }
3808 3808
3809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3810 /** 3810 /**
3811 * KickStart - Perform hard reset of MPT adapter. 3811 * KickStart - Perform hard reset of MPT adapter.
3812 * @ioc: Pointer to MPT_ADAPTER structure 3812 * @ioc: Pointer to MPT_ADAPTER structure
3813 * @force: Force hard reset 3813 * @force: Force hard reset
3814 * @sleepFlag: Specifies whether the process can sleep 3814 * @sleepFlag: Specifies whether the process can sleep
3815 * 3815 *
3816 * This routine places MPT adapter in diagnostic mode via the 3816 * This routine places MPT adapter in diagnostic mode via the
3817 * WriteSequence register, and then performs a hard reset of adapter 3817 * WriteSequence register, and then performs a hard reset of adapter
3818 * via the Diagnostic register. 3818 * via the Diagnostic register.
3819 * 3819 *
3820 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread) 3820 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3821 * or NO_SLEEP (interrupt thread, use mdelay) 3821 * or NO_SLEEP (interrupt thread, use mdelay)
3822 * force - 1 if doorbell active, board fault state 3822 * force - 1 if doorbell active, board fault state
3823 * board operational, IOC_RECOVERY or 3823 * board operational, IOC_RECOVERY or
3824 * IOC_BRINGUP and there is an alt_ioc. 3824 * IOC_BRINGUP and there is an alt_ioc.
3825 * 0 else 3825 * 0 else
3826 * 3826 *
3827 * Returns: 3827 * Returns:
3828 * 1 - hard reset, READY 3828 * 1 - hard reset, READY
3829 * 0 - no reset due to History bit, READY 3829 * 0 - no reset due to History bit, READY
3830 * -1 - no reset due to History bit but not READY 3830 * -1 - no reset due to History bit but not READY
3831 * OR reset but failed to come READY 3831 * OR reset but failed to come READY
3832 * -2 - no reset, could not enter DIAG mode 3832 * -2 - no reset, could not enter DIAG mode
3833 * -3 - reset but bad FW bit 3833 * -3 - reset but bad FW bit
3834 */ 3834 */
3835 static int 3835 static int
3836 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) 3836 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3837 { 3837 {
3838 int hard_reset_done = 0; 3838 int hard_reset_done = 0;
3839 u32 ioc_state=0; 3839 u32 ioc_state=0;
3840 int cnt,cntdn; 3840 int cnt,cntdn;
3841 3841
3842 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name)); 3842 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3843 if (ioc->bus_type == SPI) { 3843 if (ioc->bus_type == SPI) {
3844 /* Always issue a Msg Unit Reset first. This will clear some 3844 /* Always issue a Msg Unit Reset first. This will clear some
3845 * SCSI bus hang conditions. 3845 * SCSI bus hang conditions.
3846 */ 3846 */
3847 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag); 3847 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3848 3848
3849 if (sleepFlag == CAN_SLEEP) { 3849 if (sleepFlag == CAN_SLEEP) {
3850 msleep (1000); 3850 msleep (1000);
3851 } else { 3851 } else {
3852 mdelay (1000); 3852 mdelay (1000);
3853 } 3853 }
3854 } 3854 }
3855 3855
3856 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag); 3856 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3857 if (hard_reset_done < 0) 3857 if (hard_reset_done < 0)
3858 return hard_reset_done; 3858 return hard_reset_done;
3859 3859
3860 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n", 3860 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3861 ioc->name)); 3861 ioc->name));
3862 3862
3863 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */ 3863 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3864 for (cnt=0; cnt<cntdn; cnt++) { 3864 for (cnt=0; cnt<cntdn; cnt++) {
3865 ioc_state = mpt_GetIocState(ioc, 1); 3865 ioc_state = mpt_GetIocState(ioc, 1);
3866 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) { 3866 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3867 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n", 3867 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3868 ioc->name, cnt)); 3868 ioc->name, cnt));
3869 return hard_reset_done; 3869 return hard_reset_done;
3870 } 3870 }
3871 if (sleepFlag == CAN_SLEEP) { 3871 if (sleepFlag == CAN_SLEEP) {
3872 msleep (10); 3872 msleep (10);
3873 } else { 3873 } else {
3874 mdelay (10); 3874 mdelay (10);
3875 } 3875 }
3876 } 3876 }
3877 3877
3878 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n", 3878 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3879 ioc->name, mpt_GetIocState(ioc, 0))); 3879 ioc->name, mpt_GetIocState(ioc, 0)));
3880 return -1; 3880 return -1;
3881 } 3881 }
3882 3882
3883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3884 /** 3884 /**
3885 * mpt_diag_reset - Perform hard reset of the adapter. 3885 * mpt_diag_reset - Perform hard reset of the adapter.
3886 * @ioc: Pointer to MPT_ADAPTER structure 3886 * @ioc: Pointer to MPT_ADAPTER structure
3887 * @ignore: Set if to honor and clear to ignore 3887 * @ignore: Set if to honor and clear to ignore
3888 * the reset history bit 3888 * the reset history bit
3889 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread, 3889 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3890 * else set to NO_SLEEP (use mdelay instead) 3890 * else set to NO_SLEEP (use mdelay instead)
3891 * 3891 *
3892 * This routine places the adapter in diagnostic mode via the 3892 * This routine places the adapter in diagnostic mode via the
3893 * WriteSequence register and then performs a hard reset of adapter 3893 * WriteSequence register and then performs a hard reset of adapter
3894 * via the Diagnostic register. Adapter should be in ready state 3894 * via the Diagnostic register. Adapter should be in ready state
3895 * upon successful completion. 3895 * upon successful completion.
3896 * 3896 *
3897 * Returns: 1 hard reset successful 3897 * Returns: 1 hard reset successful
3898 * 0 no reset performed because reset history bit set 3898 * 0 no reset performed because reset history bit set
3899 * -2 enabling diagnostic mode failed 3899 * -2 enabling diagnostic mode failed
3900 * -3 diagnostic reset failed 3900 * -3 diagnostic reset failed
3901 */ 3901 */
3902 static int 3902 static int
3903 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) 3903 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3904 { 3904 {
3905 u32 diag0val; 3905 u32 diag0val;
3906 u32 doorbell; 3906 u32 doorbell;
3907 int hard_reset_done = 0; 3907 int hard_reset_done = 0;
3908 int count = 0; 3908 int count = 0;
3909 u32 diag1val = 0; 3909 u32 diag1val = 0;
3910 MpiFwHeader_t *cached_fw; /* Pointer to FW */ 3910 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3911 u8 cb_idx; 3911 u8 cb_idx;
3912 3912
3913 /* Clear any existing interrupts */ 3913 /* Clear any existing interrupts */
3914 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 3914 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3915 3915
3916 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { 3916 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3917 3917
3918 if (!ignore) 3918 if (!ignore)
3919 return 0; 3919 return 0;
3920 3920
3921 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " 3921 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3922 "address=%p\n", ioc->name, __func__, 3922 "address=%p\n", ioc->name, __func__,
3923 &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); 3923 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3924 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); 3924 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3925 if (sleepFlag == CAN_SLEEP) 3925 if (sleepFlag == CAN_SLEEP)
3926 msleep(1); 3926 msleep(1);
3927 else 3927 else
3928 mdelay(1); 3928 mdelay(1);
3929 3929
3930 /* 3930 /*
3931 * Call each currently registered protocol IOC reset handler 3931 * Call each currently registered protocol IOC reset handler
3932 * with pre-reset indication. 3932 * with pre-reset indication.
3933 * NOTE: If we're doing _IOC_BRINGUP, there can be no 3933 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3934 * MptResetHandlers[] registered yet. 3934 * MptResetHandlers[] registered yet.
3935 */ 3935 */
3936 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 3936 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3937 if (MptResetHandlers[cb_idx]) 3937 if (MptResetHandlers[cb_idx])
3938 (*(MptResetHandlers[cb_idx]))(ioc, 3938 (*(MptResetHandlers[cb_idx]))(ioc,
3939 MPT_IOC_PRE_RESET); 3939 MPT_IOC_PRE_RESET);
3940 } 3940 }
3941 3941
3942 for (count = 0; count < 60; count ++) { 3942 for (count = 0; count < 60; count ++) {
3943 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); 3943 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3944 doorbell &= MPI_IOC_STATE_MASK; 3944 doorbell &= MPI_IOC_STATE_MASK;
3945 3945
3946 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3946 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3947 "looking for READY STATE: doorbell=%x" 3947 "looking for READY STATE: doorbell=%x"
3948 " count=%d\n", 3948 " count=%d\n",
3949 ioc->name, doorbell, count)); 3949 ioc->name, doorbell, count));
3950 3950
3951 if (doorbell == MPI_IOC_STATE_READY) { 3951 if (doorbell == MPI_IOC_STATE_READY) {
3952 return 1; 3952 return 1;
3953 } 3953 }
3954 3954
3955 /* wait 1 sec */ 3955 /* wait 1 sec */
3956 if (sleepFlag == CAN_SLEEP) 3956 if (sleepFlag == CAN_SLEEP)
3957 msleep(1000); 3957 msleep(1000);
3958 else 3958 else
3959 mdelay(1000); 3959 mdelay(1000);
3960 } 3960 }
3961 return -1; 3961 return -1;
3962 } 3962 }
3963 3963
3964 /* Use "Diagnostic reset" method! (only thing available!) */ 3964 /* Use "Diagnostic reset" method! (only thing available!) */
3965 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3965 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3966 3966
3967 if (ioc->debug_level & MPT_DEBUG) { 3967 if (ioc->debug_level & MPT_DEBUG) {
3968 if (ioc->alt_ioc) 3968 if (ioc->alt_ioc)
3969 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 3969 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3970 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n", 3970 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3971 ioc->name, diag0val, diag1val)); 3971 ioc->name, diag0val, diag1val));
3972 } 3972 }
3973 3973
3974 /* Do the reset if we are told to ignore the reset history 3974 /* Do the reset if we are told to ignore the reset history
3975 * or if the reset history is 0 3975 * or if the reset history is 0
3976 */ 3976 */
3977 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) { 3977 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3978 while ((diag0val & MPI_DIAG_DRWE) == 0) { 3978 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3979 /* Write magic sequence to WriteSequence register 3979 /* Write magic sequence to WriteSequence register
3980 * Loop until in diagnostic mode 3980 * Loop until in diagnostic mode
3981 */ 3981 */
3982 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3982 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3983 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3983 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3984 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3984 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3985 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3985 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3986 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3986 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3987 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3987 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3988 3988
3989 /* wait 100 msec */ 3989 /* wait 100 msec */
3990 if (sleepFlag == CAN_SLEEP) { 3990 if (sleepFlag == CAN_SLEEP) {
3991 msleep (100); 3991 msleep (100);
3992 } else { 3992 } else {
3993 mdelay (100); 3993 mdelay (100);
3994 } 3994 }
3995 3995
3996 count++; 3996 count++;
3997 if (count > 20) { 3997 if (count > 20) {
3998 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n", 3998 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3999 ioc->name, diag0val); 3999 ioc->name, diag0val);
4000 return -2; 4000 return -2;
4001 4001
4002 } 4002 }
4003 4003
4004 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4004 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4005 4005
4006 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n", 4006 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4007 ioc->name, diag0val)); 4007 ioc->name, diag0val));
4008 } 4008 }
4009 4009
4010 if (ioc->debug_level & MPT_DEBUG) { 4010 if (ioc->debug_level & MPT_DEBUG) {
4011 if (ioc->alt_ioc) 4011 if (ioc->alt_ioc)
4012 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 4012 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4013 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n", 4013 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4014 ioc->name, diag0val, diag1val)); 4014 ioc->name, diag0val, diag1val));
4015 } 4015 }
4016 /* 4016 /*
4017 * Disable the ARM (Bug fix) 4017 * Disable the ARM (Bug fix)
4018 * 4018 *
4019 */ 4019 */
4020 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM); 4020 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4021 mdelay(1); 4021 mdelay(1);
4022 4022
4023 /* 4023 /*
4024 * Now hit the reset bit in the Diagnostic register 4024 * Now hit the reset bit in the Diagnostic register
4025 * (THE BIG HAMMER!) (Clears DRWE bit). 4025 * (THE BIG HAMMER!) (Clears DRWE bit).
4026 */ 4026 */
4027 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER); 4027 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4028 hard_reset_done = 1; 4028 hard_reset_done = 1;
4029 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n", 4029 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4030 ioc->name)); 4030 ioc->name));
4031 4031
4032 /* 4032 /*
4033 * Call each currently registered protocol IOC reset handler 4033 * Call each currently registered protocol IOC reset handler
4034 * with pre-reset indication. 4034 * with pre-reset indication.
4035 * NOTE: If we're doing _IOC_BRINGUP, there can be no 4035 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4036 * MptResetHandlers[] registered yet. 4036 * MptResetHandlers[] registered yet.
4037 */ 4037 */
4038 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 4038 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4039 if (MptResetHandlers[cb_idx]) { 4039 if (MptResetHandlers[cb_idx]) {
4040 mpt_signal_reset(cb_idx, 4040 mpt_signal_reset(cb_idx,
4041 ioc, MPT_IOC_PRE_RESET); 4041 ioc, MPT_IOC_PRE_RESET);
4042 if (ioc->alt_ioc) { 4042 if (ioc->alt_ioc) {
4043 mpt_signal_reset(cb_idx, 4043 mpt_signal_reset(cb_idx,
4044 ioc->alt_ioc, MPT_IOC_PRE_RESET); 4044 ioc->alt_ioc, MPT_IOC_PRE_RESET);
4045 } 4045 }
4046 } 4046 }
4047 } 4047 }
4048 4048
4049 if (ioc->cached_fw) 4049 if (ioc->cached_fw)
4050 cached_fw = (MpiFwHeader_t *)ioc->cached_fw; 4050 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4051 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) 4051 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4052 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw; 4052 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4053 else 4053 else
4054 cached_fw = NULL; 4054 cached_fw = NULL;
4055 if (cached_fw) { 4055 if (cached_fw) {
4056 /* If the DownloadBoot operation fails, the 4056 /* If the DownloadBoot operation fails, the
4057 * IOC will be left unusable. This is a fatal error 4057 * IOC will be left unusable. This is a fatal error
4058 * case. _diag_reset will return < 0 4058 * case. _diag_reset will return < 0
4059 */ 4059 */
4060 for (count = 0; count < 30; count ++) { 4060 for (count = 0; count < 30; count ++) {
4061 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4061 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4062 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { 4062 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4063 break; 4063 break;
4064 } 4064 }
4065 4065
4066 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n", 4066 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4067 ioc->name, diag0val, count)); 4067 ioc->name, diag0val, count));
4068 /* wait 1 sec */ 4068 /* wait 1 sec */
4069 if (sleepFlag == CAN_SLEEP) { 4069 if (sleepFlag == CAN_SLEEP) {
4070 msleep (1000); 4070 msleep (1000);
4071 } else { 4071 } else {
4072 mdelay (1000); 4072 mdelay (1000);
4073 } 4073 }
4074 } 4074 }
4075 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) { 4075 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4076 printk(MYIOC_s_WARN_FMT 4076 printk(MYIOC_s_WARN_FMT
4077 "firmware downloadboot failure (%d)!\n", ioc->name, count); 4077 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4078 } 4078 }
4079 4079
4080 } else { 4080 } else {
4081 /* Wait for FW to reload and for board 4081 /* Wait for FW to reload and for board
4082 * to go to the READY state. 4082 * to go to the READY state.
4083 * Maximum wait is 60 seconds. 4083 * Maximum wait is 60 seconds.
4084 * If fail, no error will check again 4084 * If fail, no error will check again
4085 * with calling program. 4085 * with calling program.
4086 */ 4086 */
4087 for (count = 0; count < 60; count ++) { 4087 for (count = 0; count < 60; count ++) {
4088 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); 4088 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4089 doorbell &= MPI_IOC_STATE_MASK; 4089 doorbell &= MPI_IOC_STATE_MASK;
4090 4090
4091 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 4091 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4092 "looking for READY STATE: doorbell=%x" 4092 "looking for READY STATE: doorbell=%x"
4093 " count=%d\n", ioc->name, doorbell, count)); 4093 " count=%d\n", ioc->name, doorbell, count));
4094 4094
4095 if (doorbell == MPI_IOC_STATE_READY) { 4095 if (doorbell == MPI_IOC_STATE_READY) {
4096 break; 4096 break;
4097 } 4097 }
4098 4098
4099 /* wait 1 sec */ 4099 /* wait 1 sec */
4100 if (sleepFlag == CAN_SLEEP) { 4100 if (sleepFlag == CAN_SLEEP) {
4101 msleep (1000); 4101 msleep (1000);
4102 } else { 4102 } else {
4103 mdelay (1000); 4103 mdelay (1000);
4104 } 4104 }
4105 } 4105 }
4106 4106
4107 if (doorbell != MPI_IOC_STATE_READY) 4107 if (doorbell != MPI_IOC_STATE_READY)
4108 printk(MYIOC_s_ERR_FMT "Failed to come READY " 4108 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4109 "after reset! IocState=%x", ioc->name, 4109 "after reset! IocState=%x", ioc->name,
4110 doorbell); 4110 doorbell);
4111 } 4111 }
4112 } 4112 }
4113 4113
4114 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4114 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4115 if (ioc->debug_level & MPT_DEBUG) { 4115 if (ioc->debug_level & MPT_DEBUG) {
4116 if (ioc->alt_ioc) 4116 if (ioc->alt_ioc)
4117 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 4117 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4118 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n", 4118 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4119 ioc->name, diag0val, diag1val)); 4119 ioc->name, diag0val, diag1val));
4120 } 4120 }
4121 4121
4122 /* Clear RESET_HISTORY bit! Place board in the 4122 /* Clear RESET_HISTORY bit! Place board in the
4123 * diagnostic mode to update the diag register. 4123 * diagnostic mode to update the diag register.
4124 */ 4124 */
4125 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4125 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4126 count = 0; 4126 count = 0;
4127 while ((diag0val & MPI_DIAG_DRWE) == 0) { 4127 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4128 /* Write magic sequence to WriteSequence register 4128 /* Write magic sequence to WriteSequence register
4129 * Loop until in diagnostic mode 4129 * Loop until in diagnostic mode
4130 */ 4130 */
4131 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 4131 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4132 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 4132 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4133 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 4133 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4134 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 4134 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4135 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 4135 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4136 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 4136 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4137 4137
4138 /* wait 100 msec */ 4138 /* wait 100 msec */
4139 if (sleepFlag == CAN_SLEEP) { 4139 if (sleepFlag == CAN_SLEEP) {
4140 msleep (100); 4140 msleep (100);
4141 } else { 4141 } else {
4142 mdelay (100); 4142 mdelay (100);
4143 } 4143 }
4144 4144
4145 count++; 4145 count++;
4146 if (count > 20) { 4146 if (count > 20) {
4147 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n", 4147 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4148 ioc->name, diag0val); 4148 ioc->name, diag0val);
4149 break; 4149 break;
4150 } 4150 }
4151 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4151 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4152 } 4152 }
4153 diag0val &= ~MPI_DIAG_RESET_HISTORY; 4153 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4154 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); 4154 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4155 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4155 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4156 if (diag0val & MPI_DIAG_RESET_HISTORY) { 4156 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4157 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n", 4157 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4158 ioc->name); 4158 ioc->name);
4159 } 4159 }
4160 4160
4161 /* Disable Diagnostic Mode 4161 /* Disable Diagnostic Mode
4162 */ 4162 */
4163 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF); 4163 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4164 4164
4165 /* Check FW reload status flags. 4165 /* Check FW reload status flags.
4166 */ 4166 */
4167 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4167 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4168 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) { 4168 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4169 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n", 4169 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4170 ioc->name, diag0val); 4170 ioc->name, diag0val);
4171 return -3; 4171 return -3;
4172 } 4172 }
4173 4173
4174 if (ioc->debug_level & MPT_DEBUG) { 4174 if (ioc->debug_level & MPT_DEBUG) {
4175 if (ioc->alt_ioc) 4175 if (ioc->alt_ioc)
4176 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 4176 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4177 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n", 4177 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4178 ioc->name, diag0val, diag1val)); 4178 ioc->name, diag0val, diag1val));
4179 } 4179 }
4180 4180
4181 /* 4181 /*
4182 * Reset flag that says we've enabled event notification 4182 * Reset flag that says we've enabled event notification
4183 */ 4183 */
4184 ioc->facts.EventState = 0; 4184 ioc->facts.EventState = 0;
4185 4185
4186 if (ioc->alt_ioc) 4186 if (ioc->alt_ioc)
4187 ioc->alt_ioc->facts.EventState = 0; 4187 ioc->alt_ioc->facts.EventState = 0;
4188 4188
4189 return hard_reset_done; 4189 return hard_reset_done;
4190 } 4190 }
4191 4191
4192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4193 /** 4193 /**
4194 * SendIocReset - Send IOCReset request to MPT adapter. 4194 * SendIocReset - Send IOCReset request to MPT adapter.
4195 * @ioc: Pointer to MPT_ADAPTER structure 4195 * @ioc: Pointer to MPT_ADAPTER structure
4196 * @reset_type: reset type, expected values are 4196 * @reset_type: reset type, expected values are
4197 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET 4197 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4198 * @sleepFlag: Specifies whether the process can sleep 4198 * @sleepFlag: Specifies whether the process can sleep
4199 * 4199 *
4200 * Send IOCReset request to the MPT adapter. 4200 * Send IOCReset request to the MPT adapter.
4201 * 4201 *
4202 * Returns 0 for success, non-zero for failure. 4202 * Returns 0 for success, non-zero for failure.
4203 */ 4203 */
4204 static int 4204 static int
4205 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag) 4205 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4206 { 4206 {
4207 int r; 4207 int r;
4208 u32 state; 4208 u32 state;
4209 int cntdn, count; 4209 int cntdn, count;
4210 4210
4211 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n", 4211 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4212 ioc->name, reset_type)); 4212 ioc->name, reset_type));
4213 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT); 4213 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4214 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 4214 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4215 return r; 4215 return r;
4216 4216
4217 /* FW ACK'd request, wait for READY state 4217 /* FW ACK'd request, wait for READY state
4218 */ 4218 */
4219 count = 0; 4219 count = 0;
4220 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */ 4220 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4221 4221
4222 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { 4222 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4223 cntdn--; 4223 cntdn--;
4224 count++; 4224 count++;
4225 if (!cntdn) { 4225 if (!cntdn) {
4226 if (sleepFlag != CAN_SLEEP) 4226 if (sleepFlag != CAN_SLEEP)
4227 count *= 10; 4227 count *= 10;
4228 4228
4229 printk(MYIOC_s_ERR_FMT 4229 printk(MYIOC_s_ERR_FMT
4230 "Wait IOC_READY state (0x%x) timeout(%d)!\n", 4230 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4231 ioc->name, state, (int)((count+5)/HZ)); 4231 ioc->name, state, (int)((count+5)/HZ));
4232 return -ETIME; 4232 return -ETIME;
4233 } 4233 }
4234 4234
4235 if (sleepFlag == CAN_SLEEP) { 4235 if (sleepFlag == CAN_SLEEP) {
4236 msleep(1); 4236 msleep(1);
4237 } else { 4237 } else {
4238 mdelay (1); /* 1 msec delay */ 4238 mdelay (1); /* 1 msec delay */
4239 } 4239 }
4240 } 4240 }
4241 4241
4242 /* TODO! 4242 /* TODO!
4243 * Cleanup all event stuff for this IOC; re-issue EventNotification 4243 * Cleanup all event stuff for this IOC; re-issue EventNotification
4244 * request if needed. 4244 * request if needed.
4245 */ 4245 */
4246 if (ioc->facts.Function) 4246 if (ioc->facts.Function)
4247 ioc->facts.EventState = 0; 4247 ioc->facts.EventState = 0;
4248 4248
4249 return 0; 4249 return 0;
4250 } 4250 }
4251 4251
4252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4253 /** 4253 /**
4254 * initChainBuffers - Allocate memory for and initialize chain buffers 4254 * initChainBuffers - Allocate memory for and initialize chain buffers
4255 * @ioc: Pointer to MPT_ADAPTER structure 4255 * @ioc: Pointer to MPT_ADAPTER structure
4256 * 4256 *
4257 * Allocates memory for and initializes chain buffers, 4257 * Allocates memory for and initializes chain buffers,
4258 * chain buffer control arrays and spinlock. 4258 * chain buffer control arrays and spinlock.
4259 */ 4259 */
4260 static int 4260 static int
4261 initChainBuffers(MPT_ADAPTER *ioc) 4261 initChainBuffers(MPT_ADAPTER *ioc)
4262 { 4262 {
4263 u8 *mem; 4263 u8 *mem;
4264 int sz, ii, num_chain; 4264 int sz, ii, num_chain;
4265 int scale, num_sge, numSGE; 4265 int scale, num_sge, numSGE;
4266 4266
4267 /* ReqToChain size must equal the req_depth 4267 /* ReqToChain size must equal the req_depth
4268 * index = req_idx 4268 * index = req_idx
4269 */ 4269 */
4270 if (ioc->ReqToChain == NULL) { 4270 if (ioc->ReqToChain == NULL) {
4271 sz = ioc->req_depth * sizeof(int); 4271 sz = ioc->req_depth * sizeof(int);
4272 mem = kmalloc(sz, GFP_ATOMIC); 4272 mem = kmalloc(sz, GFP_ATOMIC);
4273 if (mem == NULL) 4273 if (mem == NULL)
4274 return -1; 4274 return -1;
4275 4275
4276 ioc->ReqToChain = (int *) mem; 4276 ioc->ReqToChain = (int *) mem;
4277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n", 4277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4278 ioc->name, mem, sz)); 4278 ioc->name, mem, sz));
4279 mem = kmalloc(sz, GFP_ATOMIC); 4279 mem = kmalloc(sz, GFP_ATOMIC);
4280 if (mem == NULL) 4280 if (mem == NULL)
4281 return -1; 4281 return -1;
4282 4282
4283 ioc->RequestNB = (int *) mem; 4283 ioc->RequestNB = (int *) mem;
4284 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n", 4284 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4285 ioc->name, mem, sz)); 4285 ioc->name, mem, sz));
4286 } 4286 }
4287 for (ii = 0; ii < ioc->req_depth; ii++) { 4287 for (ii = 0; ii < ioc->req_depth; ii++) {
4288 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN; 4288 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4289 } 4289 }
4290 4290
4291 /* ChainToChain size must equal the total number 4291 /* ChainToChain size must equal the total number
4292 * of chain buffers to be allocated. 4292 * of chain buffers to be allocated.
4293 * index = chain_idx 4293 * index = chain_idx
4294 * 4294 *
4295 * Calculate the number of chain buffers needed(plus 1) per I/O 4295 * Calculate the number of chain buffers needed(plus 1) per I/O
4296 * then multiply the maximum number of simultaneous cmds 4296 * then multiply the maximum number of simultaneous cmds
4297 * 4297 *
4298 * num_sge = num sge in request frame + last chain buffer 4298 * num_sge = num sge in request frame + last chain buffer
4299 * scale = num sge per chain buffer if no chain element 4299 * scale = num sge per chain buffer if no chain element
4300 */ 4300 */
4301 scale = ioc->req_sz / ioc->SGE_size; 4301 scale = ioc->req_sz / ioc->SGE_size;
4302 if (ioc->sg_addr_size == sizeof(u64)) 4302 if (ioc->sg_addr_size == sizeof(u64))
4303 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size; 4303 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4304 else 4304 else
4305 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size; 4305 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4306 4306
4307 if (ioc->sg_addr_size == sizeof(u64)) { 4307 if (ioc->sg_addr_size == sizeof(u64)) {
4308 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + 4308 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4309 (ioc->req_sz - 60) / ioc->SGE_size; 4309 (ioc->req_sz - 60) / ioc->SGE_size;
4310 } else { 4310 } else {
4311 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + 4311 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4312 scale + (ioc->req_sz - 64) / ioc->SGE_size; 4312 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4313 } 4313 }
4314 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n", 4314 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4315 ioc->name, num_sge, numSGE)); 4315 ioc->name, num_sge, numSGE));
4316 4316
4317 if (ioc->bus_type == FC) { 4317 if (ioc->bus_type == FC) {
4318 if (numSGE > MPT_SCSI_FC_SG_DEPTH) 4318 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4319 numSGE = MPT_SCSI_FC_SG_DEPTH; 4319 numSGE = MPT_SCSI_FC_SG_DEPTH;
4320 } else { 4320 } else {
4321 if (numSGE > MPT_SCSI_SG_DEPTH) 4321 if (numSGE > MPT_SCSI_SG_DEPTH)
4322 numSGE = MPT_SCSI_SG_DEPTH; 4322 numSGE = MPT_SCSI_SG_DEPTH;
4323 } 4323 }
4324 4324
4325 num_chain = 1; 4325 num_chain = 1;
4326 while (numSGE - num_sge > 0) { 4326 while (numSGE - num_sge > 0) {
4327 num_chain++; 4327 num_chain++;
4328 num_sge += (scale - 1); 4328 num_sge += (scale - 1);
4329 } 4329 }
4330 num_chain++; 4330 num_chain++;
4331 4331
4332 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n", 4332 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4333 ioc->name, numSGE, num_sge, num_chain)); 4333 ioc->name, numSGE, num_sge, num_chain));
4334 4334
4335 if (ioc->bus_type == SPI) 4335 if (ioc->bus_type == SPI)
4336 num_chain *= MPT_SCSI_CAN_QUEUE; 4336 num_chain *= MPT_SCSI_CAN_QUEUE;
4337 else if (ioc->bus_type == SAS) 4337 else if (ioc->bus_type == SAS)
4338 num_chain *= MPT_SAS_CAN_QUEUE; 4338 num_chain *= MPT_SAS_CAN_QUEUE;
4339 else 4339 else
4340 num_chain *= MPT_FC_CAN_QUEUE; 4340 num_chain *= MPT_FC_CAN_QUEUE;
4341 4341
4342 ioc->num_chain = num_chain; 4342 ioc->num_chain = num_chain;
4343 4343
4344 sz = num_chain * sizeof(int); 4344 sz = num_chain * sizeof(int);
4345 if (ioc->ChainToChain == NULL) { 4345 if (ioc->ChainToChain == NULL) {
4346 mem = kmalloc(sz, GFP_ATOMIC); 4346 mem = kmalloc(sz, GFP_ATOMIC);
4347 if (mem == NULL) 4347 if (mem == NULL)
4348 return -1; 4348 return -1;
4349 4349
4350 ioc->ChainToChain = (int *) mem; 4350 ioc->ChainToChain = (int *) mem;
4351 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n", 4351 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4352 ioc->name, mem, sz)); 4352 ioc->name, mem, sz));
4353 } else { 4353 } else {
4354 mem = (u8 *) ioc->ChainToChain; 4354 mem = (u8 *) ioc->ChainToChain;
4355 } 4355 }
4356 memset(mem, 0xFF, sz); 4356 memset(mem, 0xFF, sz);
4357 return num_chain; 4357 return num_chain;
4358 } 4358 }
4359 4359
4360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4361 /** 4361 /**
4362 * PrimeIocFifos - Initialize IOC request and reply FIFOs. 4362 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4363 * @ioc: Pointer to MPT_ADAPTER structure 4363 * @ioc: Pointer to MPT_ADAPTER structure
4364 * 4364 *
4365 * This routine allocates memory for the MPT reply and request frame 4365 * This routine allocates memory for the MPT reply and request frame
4366 * pools (if necessary), and primes the IOC reply FIFO with 4366 * pools (if necessary), and primes the IOC reply FIFO with
4367 * reply frames. 4367 * reply frames.
4368 * 4368 *
4369 * Returns 0 for success, non-zero for failure. 4369 * Returns 0 for success, non-zero for failure.
4370 */ 4370 */
4371 static int 4371 static int
4372 PrimeIocFifos(MPT_ADAPTER *ioc) 4372 PrimeIocFifos(MPT_ADAPTER *ioc)
4373 { 4373 {
4374 MPT_FRAME_HDR *mf; 4374 MPT_FRAME_HDR *mf;
4375 unsigned long flags; 4375 unsigned long flags;
4376 dma_addr_t alloc_dma; 4376 dma_addr_t alloc_dma;
4377 u8 *mem; 4377 u8 *mem;
4378 int i, reply_sz, sz, total_size, num_chain; 4378 int i, reply_sz, sz, total_size, num_chain;
4379 u64 dma_mask; 4379 u64 dma_mask;
4380 4380
4381 dma_mask = 0; 4381 dma_mask = 0;
4382 4382
4383 /* Prime reply FIFO... */ 4383 /* Prime reply FIFO... */
4384 4384
4385 if (ioc->reply_frames == NULL) { 4385 if (ioc->reply_frames == NULL) {
4386 if ( (num_chain = initChainBuffers(ioc)) < 0) 4386 if ( (num_chain = initChainBuffers(ioc)) < 0)
4387 return -1; 4387 return -1;
4388 /* 4388 /*
4389 * 1078 errata workaround for the 36GB limitation 4389 * 1078 errata workaround for the 36GB limitation
4390 */ 4390 */
4391 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 && 4391 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4392 ioc->dma_mask > DMA_BIT_MASK(35)) { 4392 ioc->dma_mask > DMA_BIT_MASK(35)) {
4393 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32)) 4393 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4394 && !pci_set_consistent_dma_mask(ioc->pcidev, 4394 && !pci_set_consistent_dma_mask(ioc->pcidev,
4395 DMA_BIT_MASK(32))) { 4395 DMA_BIT_MASK(32))) {
4396 dma_mask = DMA_BIT_MASK(35); 4396 dma_mask = DMA_BIT_MASK(35);
4397 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT 4397 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4398 "setting 35 bit addressing for " 4398 "setting 35 bit addressing for "
4399 "Request/Reply/Chain and Sense Buffers\n", 4399 "Request/Reply/Chain and Sense Buffers\n",
4400 ioc->name)); 4400 ioc->name));
4401 } else { 4401 } else {
4402 /*Reseting DMA mask to 64 bit*/ 4402 /*Reseting DMA mask to 64 bit*/
4403 pci_set_dma_mask(ioc->pcidev, 4403 pci_set_dma_mask(ioc->pcidev,
4404 DMA_BIT_MASK(64)); 4404 DMA_BIT_MASK(64));
4405 pci_set_consistent_dma_mask(ioc->pcidev, 4405 pci_set_consistent_dma_mask(ioc->pcidev,
4406 DMA_BIT_MASK(64)); 4406 DMA_BIT_MASK(64));
4407 4407
4408 printk(MYIOC_s_ERR_FMT 4408 printk(MYIOC_s_ERR_FMT
4409 "failed setting 35 bit addressing for " 4409 "failed setting 35 bit addressing for "
4410 "Request/Reply/Chain and Sense Buffers\n", 4410 "Request/Reply/Chain and Sense Buffers\n",
4411 ioc->name); 4411 ioc->name);
4412 return -1; 4412 return -1;
4413 } 4413 }
4414 } 4414 }
4415 4415
4416 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth); 4416 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4417 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n", 4417 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4418 ioc->name, ioc->reply_sz, ioc->reply_depth)); 4418 ioc->name, ioc->reply_sz, ioc->reply_depth));
4419 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n", 4419 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4420 ioc->name, reply_sz, reply_sz)); 4420 ioc->name, reply_sz, reply_sz));
4421 4421
4422 sz = (ioc->req_sz * ioc->req_depth); 4422 sz = (ioc->req_sz * ioc->req_depth);
4423 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n", 4423 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4424 ioc->name, ioc->req_sz, ioc->req_depth)); 4424 ioc->name, ioc->req_sz, ioc->req_depth));
4425 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n", 4425 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4426 ioc->name, sz, sz)); 4426 ioc->name, sz, sz));
4427 total_size += sz; 4427 total_size += sz;
4428 4428
4429 sz = num_chain * ioc->req_sz; /* chain buffer pool size */ 4429 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4430 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n", 4430 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4431 ioc->name, ioc->req_sz, num_chain)); 4431 ioc->name, ioc->req_sz, num_chain));
4432 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n", 4432 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4433 ioc->name, sz, sz, num_chain)); 4433 ioc->name, sz, sz, num_chain));
4434 4434
4435 total_size += sz; 4435 total_size += sz;
4436 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma); 4436 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4437 if (mem == NULL) { 4437 if (mem == NULL) {
4438 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n", 4438 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4439 ioc->name); 4439 ioc->name);
4440 goto out_fail; 4440 goto out_fail;
4441 } 4441 }
4442 4442
4443 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n", 4443 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4444 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size)); 4444 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4445 4445
4446 memset(mem, 0, total_size); 4446 memset(mem, 0, total_size);
4447 ioc->alloc_total += total_size; 4447 ioc->alloc_total += total_size;
4448 ioc->alloc = mem; 4448 ioc->alloc = mem;
4449 ioc->alloc_dma = alloc_dma; 4449 ioc->alloc_dma = alloc_dma;
4450 ioc->alloc_sz = total_size; 4450 ioc->alloc_sz = total_size;
4451 ioc->reply_frames = (MPT_FRAME_HDR *) mem; 4451 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4452 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); 4452 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4453 4453
4454 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n", 4454 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4455 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma)); 4455 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4456 4456
4457 alloc_dma += reply_sz; 4457 alloc_dma += reply_sz;
4458 mem += reply_sz; 4458 mem += reply_sz;
4459 4459
4460 /* Request FIFO - WE manage this! */ 4460 /* Request FIFO - WE manage this! */
4461 4461
4462 ioc->req_frames = (MPT_FRAME_HDR *) mem; 4462 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4463 ioc->req_frames_dma = alloc_dma; 4463 ioc->req_frames_dma = alloc_dma;
4464 4464
4465 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n", 4465 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4466 ioc->name, mem, (void *)(ulong)alloc_dma)); 4466 ioc->name, mem, (void *)(ulong)alloc_dma));
4467 4467
4468 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); 4468 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4469 4469
4470 #if defined(CONFIG_MTRR) && 0 4470 #if defined(CONFIG_MTRR) && 0
4471 /* 4471 /*
4472 * Enable Write Combining MTRR for IOC's memory region. 4472 * Enable Write Combining MTRR for IOC's memory region.
4473 * (at least as much as we can; "size and base must be 4473 * (at least as much as we can; "size and base must be
4474 * multiples of 4 kiB" 4474 * multiples of 4 kiB"
4475 */ 4475 */
4476 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma, 4476 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4477 sz, 4477 sz,
4478 MTRR_TYPE_WRCOMB, 1); 4478 MTRR_TYPE_WRCOMB, 1);
4479 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n", 4479 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4480 ioc->name, ioc->req_frames_dma, sz)); 4480 ioc->name, ioc->req_frames_dma, sz));
4481 #endif 4481 #endif
4482 4482
4483 for (i = 0; i < ioc->req_depth; i++) { 4483 for (i = 0; i < ioc->req_depth; i++) {
4484 alloc_dma += ioc->req_sz; 4484 alloc_dma += ioc->req_sz;
4485 mem += ioc->req_sz; 4485 mem += ioc->req_sz;
4486 } 4486 }
4487 4487
4488 ioc->ChainBuffer = mem; 4488 ioc->ChainBuffer = mem;
4489 ioc->ChainBufferDMA = alloc_dma; 4489 ioc->ChainBufferDMA = alloc_dma;
4490 4490
4491 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n", 4491 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4492 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA)); 4492 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4493 4493
4494 /* Initialize the free chain Q. 4494 /* Initialize the free chain Q.
4495 */ 4495 */
4496 4496
4497 INIT_LIST_HEAD(&ioc->FreeChainQ); 4497 INIT_LIST_HEAD(&ioc->FreeChainQ);
4498 4498
4499 /* Post the chain buffers to the FreeChainQ. 4499 /* Post the chain buffers to the FreeChainQ.
4500 */ 4500 */
4501 mem = (u8 *)ioc->ChainBuffer; 4501 mem = (u8 *)ioc->ChainBuffer;
4502 for (i=0; i < num_chain; i++) { 4502 for (i=0; i < num_chain; i++) {
4503 mf = (MPT_FRAME_HDR *) mem; 4503 mf = (MPT_FRAME_HDR *) mem;
4504 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ); 4504 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4505 mem += ioc->req_sz; 4505 mem += ioc->req_sz;
4506 } 4506 }
4507 4507
4508 /* Initialize Request frames linked list 4508 /* Initialize Request frames linked list
4509 */ 4509 */
4510 alloc_dma = ioc->req_frames_dma; 4510 alloc_dma = ioc->req_frames_dma;
4511 mem = (u8 *) ioc->req_frames; 4511 mem = (u8 *) ioc->req_frames;
4512 4512
4513 spin_lock_irqsave(&ioc->FreeQlock, flags); 4513 spin_lock_irqsave(&ioc->FreeQlock, flags);
4514 INIT_LIST_HEAD(&ioc->FreeQ); 4514 INIT_LIST_HEAD(&ioc->FreeQ);
4515 for (i = 0; i < ioc->req_depth; i++) { 4515 for (i = 0; i < ioc->req_depth; i++) {
4516 mf = (MPT_FRAME_HDR *) mem; 4516 mf = (MPT_FRAME_HDR *) mem;
4517 4517
4518 /* Queue REQUESTs *internally*! */ 4518 /* Queue REQUESTs *internally*! */
4519 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 4519 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4520 4520
4521 mem += ioc->req_sz; 4521 mem += ioc->req_sz;
4522 } 4522 }
4523 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 4523 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4524 4524
4525 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 4525 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4526 ioc->sense_buf_pool = 4526 ioc->sense_buf_pool =
4527 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma); 4527 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4528 if (ioc->sense_buf_pool == NULL) { 4528 if (ioc->sense_buf_pool == NULL) {
4529 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n", 4529 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4530 ioc->name); 4530 ioc->name);
4531 goto out_fail; 4531 goto out_fail;
4532 } 4532 }
4533 4533
4534 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF); 4534 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4535 ioc->alloc_total += sz; 4535 ioc->alloc_total += sz;
4536 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n", 4536 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4537 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma)); 4537 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4538 4538
4539 } 4539 }
4540 4540
4541 /* Post Reply frames to FIFO 4541 /* Post Reply frames to FIFO
4542 */ 4542 */
4543 alloc_dma = ioc->alloc_dma; 4543 alloc_dma = ioc->alloc_dma;
4544 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n", 4544 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4545 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma)); 4545 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4546 4546
4547 for (i = 0; i < ioc->reply_depth; i++) { 4547 for (i = 0; i < ioc->reply_depth; i++) {
4548 /* Write each address to the IOC! */ 4548 /* Write each address to the IOC! */
4549 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma); 4549 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4550 alloc_dma += ioc->reply_sz; 4550 alloc_dma += ioc->reply_sz;
4551 } 4551 }
4552 4552
4553 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev, 4553 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4554 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev, 4554 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4555 ioc->dma_mask)) 4555 ioc->dma_mask))
4556 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT 4556 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4557 "restoring 64 bit addressing\n", ioc->name)); 4557 "restoring 64 bit addressing\n", ioc->name));
4558 4558
4559 return 0; 4559 return 0;
4560 4560
4561 out_fail: 4561 out_fail:
4562 4562
4563 if (ioc->alloc != NULL) { 4563 if (ioc->alloc != NULL) {
4564 sz = ioc->alloc_sz; 4564 sz = ioc->alloc_sz;
4565 pci_free_consistent(ioc->pcidev, 4565 pci_free_consistent(ioc->pcidev,
4566 sz, 4566 sz,
4567 ioc->alloc, ioc->alloc_dma); 4567 ioc->alloc, ioc->alloc_dma);
4568 ioc->reply_frames = NULL; 4568 ioc->reply_frames = NULL;
4569 ioc->req_frames = NULL; 4569 ioc->req_frames = NULL;
4570 ioc->alloc_total -= sz; 4570 ioc->alloc_total -= sz;
4571 } 4571 }
4572 if (ioc->sense_buf_pool != NULL) { 4572 if (ioc->sense_buf_pool != NULL) {
4573 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 4573 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4574 pci_free_consistent(ioc->pcidev, 4574 pci_free_consistent(ioc->pcidev,
4575 sz, 4575 sz,
4576 ioc->sense_buf_pool, ioc->sense_buf_pool_dma); 4576 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4577 ioc->sense_buf_pool = NULL; 4577 ioc->sense_buf_pool = NULL;
4578 } 4578 }
4579 4579
4580 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev, 4580 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4581 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev, 4581 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4582 DMA_BIT_MASK(64))) 4582 DMA_BIT_MASK(64)))
4583 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT 4583 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4584 "restoring 64 bit addressing\n", ioc->name)); 4584 "restoring 64 bit addressing\n", ioc->name));
4585 4585
4586 return -1; 4586 return -1;
4587 } 4587 }
4588 4588
4589 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4589 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4590 /** 4590 /**
4591 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply 4591 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4592 * from IOC via doorbell handshake method. 4592 * from IOC via doorbell handshake method.
4593 * @ioc: Pointer to MPT_ADAPTER structure 4593 * @ioc: Pointer to MPT_ADAPTER structure
4594 * @reqBytes: Size of the request in bytes 4594 * @reqBytes: Size of the request in bytes
4595 * @req: Pointer to MPT request frame 4595 * @req: Pointer to MPT request frame
4596 * @replyBytes: Expected size of the reply in bytes 4596 * @replyBytes: Expected size of the reply in bytes
4597 * @u16reply: Pointer to area where reply should be written 4597 * @u16reply: Pointer to area where reply should be written
4598 * @maxwait: Max wait time for a reply (in seconds) 4598 * @maxwait: Max wait time for a reply (in seconds)
4599 * @sleepFlag: Specifies whether the process can sleep 4599 * @sleepFlag: Specifies whether the process can sleep
4600 * 4600 *
4601 * NOTES: It is the callers responsibility to byte-swap fields in the 4601 * NOTES: It is the callers responsibility to byte-swap fields in the
4602 * request which are greater than 1 byte in size. It is also the 4602 * request which are greater than 1 byte in size. It is also the
4603 * callers responsibility to byte-swap response fields which are 4603 * callers responsibility to byte-swap response fields which are
4604 * greater than 1 byte in size. 4604 * greater than 1 byte in size.
4605 * 4605 *
4606 * Returns 0 for success, non-zero for failure. 4606 * Returns 0 for success, non-zero for failure.
4607 */ 4607 */
4608 static int 4608 static int
4609 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, 4609 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4610 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag) 4610 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4611 { 4611 {
4612 MPIDefaultReply_t *mptReply; 4612 MPIDefaultReply_t *mptReply;
4613 int failcnt = 0; 4613 int failcnt = 0;
4614 int t; 4614 int t;
4615 4615
4616 /* 4616 /*
4617 * Get ready to cache a handshake reply 4617 * Get ready to cache a handshake reply
4618 */ 4618 */
4619 ioc->hs_reply_idx = 0; 4619 ioc->hs_reply_idx = 0;
4620 mptReply = (MPIDefaultReply_t *) ioc->hs_reply; 4620 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4621 mptReply->MsgLength = 0; 4621 mptReply->MsgLength = 0;
4622 4622
4623 /* 4623 /*
4624 * Make sure there are no doorbells (WRITE 0 to IntStatus reg), 4624 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4625 * then tell IOC that we want to handshake a request of N words. 4625 * then tell IOC that we want to handshake a request of N words.
4626 * (WRITE u32val to Doorbell reg). 4626 * (WRITE u32val to Doorbell reg).
4627 */ 4627 */
4628 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4628 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4629 CHIPREG_WRITE32(&ioc->chip->Doorbell, 4629 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4630 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) | 4630 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4631 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))); 4631 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4632 4632
4633 /* 4633 /*
4634 * Wait for IOC's doorbell handshake int 4634 * Wait for IOC's doorbell handshake int
4635 */ 4635 */
4636 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4636 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4637 failcnt++; 4637 failcnt++;
4638 4638
4639 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n", 4639 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4640 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); 4640 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4641 4641
4642 /* Read doorbell and check for active bit */ 4642 /* Read doorbell and check for active bit */
4643 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE)) 4643 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4644 return -1; 4644 return -1;
4645 4645
4646 /* 4646 /*
4647 * Clear doorbell int (WRITE 0 to IntStatus reg), 4647 * Clear doorbell int (WRITE 0 to IntStatus reg),
4648 * then wait for IOC to ACKnowledge that it's ready for 4648 * then wait for IOC to ACKnowledge that it's ready for
4649 * our handshake request. 4649 * our handshake request.
4650 */ 4650 */
4651 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4651 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4652 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 4652 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4653 failcnt++; 4653 failcnt++;
4654 4654
4655 if (!failcnt) { 4655 if (!failcnt) {
4656 int ii; 4656 int ii;
4657 u8 *req_as_bytes = (u8 *) req; 4657 u8 *req_as_bytes = (u8 *) req;
4658 4658
4659 /* 4659 /*
4660 * Stuff request words via doorbell handshake, 4660 * Stuff request words via doorbell handshake,
4661 * with ACK from IOC for each. 4661 * with ACK from IOC for each.
4662 */ 4662 */
4663 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) { 4663 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4664 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) | 4664 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4665 (req_as_bytes[(ii*4) + 1] << 8) | 4665 (req_as_bytes[(ii*4) + 1] << 8) |
4666 (req_as_bytes[(ii*4) + 2] << 16) | 4666 (req_as_bytes[(ii*4) + 2] << 16) |
4667 (req_as_bytes[(ii*4) + 3] << 24)); 4667 (req_as_bytes[(ii*4) + 3] << 24));
4668 4668
4669 CHIPREG_WRITE32(&ioc->chip->Doorbell, word); 4669 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4670 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 4670 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4671 failcnt++; 4671 failcnt++;
4672 } 4672 }
4673 4673
4674 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req)); 4674 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4675 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req); 4675 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4676 4676
4677 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n", 4677 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4678 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : "")); 4678 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4679 4679
4680 /* 4680 /*
4681 * Wait for completion of doorbell handshake reply from the IOC 4681 * Wait for completion of doorbell handshake reply from the IOC
4682 */ 4682 */
4683 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0) 4683 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4684 failcnt++; 4684 failcnt++;
4685 4685
4686 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n", 4686 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4687 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : "")); 4687 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4688 4688
4689 /* 4689 /*
4690 * Copy out the cached reply... 4690 * Copy out the cached reply...
4691 */ 4691 */
4692 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++) 4692 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4693 u16reply[ii] = ioc->hs_reply[ii]; 4693 u16reply[ii] = ioc->hs_reply[ii];
4694 } else { 4694 } else {
4695 return -99; 4695 return -99;
4696 } 4696 }
4697 4697
4698 return -failcnt; 4698 return -failcnt;
4699 } 4699 }
4700 4700
4701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4702 /** 4702 /**
4703 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge 4703 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4704 * @ioc: Pointer to MPT_ADAPTER structure 4704 * @ioc: Pointer to MPT_ADAPTER structure
4705 * @howlong: How long to wait (in seconds) 4705 * @howlong: How long to wait (in seconds)
4706 * @sleepFlag: Specifies whether the process can sleep 4706 * @sleepFlag: Specifies whether the process can sleep
4707 * 4707 *
4708 * This routine waits (up to ~2 seconds max) for IOC doorbell 4708 * This routine waits (up to ~2 seconds max) for IOC doorbell
4709 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS 4709 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4710 * bit in its IntStatus register being clear. 4710 * bit in its IntStatus register being clear.
4711 * 4711 *
4712 * Returns a negative value on failure, else wait loop count. 4712 * Returns a negative value on failure, else wait loop count.
4713 */ 4713 */
4714 static int 4714 static int
4715 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4715 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4716 { 4716 {
4717 int cntdn; 4717 int cntdn;
4718 int count = 0; 4718 int count = 0;
4719 u32 intstat=0; 4719 u32 intstat=0;
4720 4720
4721 cntdn = 1000 * howlong; 4721 cntdn = 1000 * howlong;
4722 4722
4723 if (sleepFlag == CAN_SLEEP) { 4723 if (sleepFlag == CAN_SLEEP) {
4724 while (--cntdn) { 4724 while (--cntdn) {
4725 msleep (1); 4725 msleep (1);
4726 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4726 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4727 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 4727 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4728 break; 4728 break;
4729 count++; 4729 count++;
4730 } 4730 }
4731 } else { 4731 } else {
4732 while (--cntdn) { 4732 while (--cntdn) {
4733 udelay (1000); 4733 udelay (1000);
4734 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4734 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4735 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 4735 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4736 break; 4736 break;
4737 count++; 4737 count++;
4738 } 4738 }
4739 } 4739 }
4740 4740
4741 if (cntdn) { 4741 if (cntdn) {
4742 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n", 4742 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4743 ioc->name, count)); 4743 ioc->name, count));
4744 return count; 4744 return count;
4745 } 4745 }
4746 4746
4747 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n", 4747 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4748 ioc->name, count, intstat); 4748 ioc->name, count, intstat);
4749 return -1; 4749 return -1;
4750 } 4750 }
4751 4751
4752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4753 /** 4753 /**
4754 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit 4754 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4755 * @ioc: Pointer to MPT_ADAPTER structure 4755 * @ioc: Pointer to MPT_ADAPTER structure
4756 * @howlong: How long to wait (in seconds) 4756 * @howlong: How long to wait (in seconds)
4757 * @sleepFlag: Specifies whether the process can sleep 4757 * @sleepFlag: Specifies whether the process can sleep
4758 * 4758 *
4759 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt 4759 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4760 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register. 4760 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4761 * 4761 *
4762 * Returns a negative value on failure, else wait loop count. 4762 * Returns a negative value on failure, else wait loop count.
4763 */ 4763 */
4764 static int 4764 static int
4765 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4765 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4766 { 4766 {
4767 int cntdn; 4767 int cntdn;
4768 int count = 0; 4768 int count = 0;
4769 u32 intstat=0; 4769 u32 intstat=0;
4770 4770
4771 cntdn = 1000 * howlong; 4771 cntdn = 1000 * howlong;
4772 if (sleepFlag == CAN_SLEEP) { 4772 if (sleepFlag == CAN_SLEEP) {
4773 while (--cntdn) { 4773 while (--cntdn) {
4774 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4774 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4775 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 4775 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4776 break; 4776 break;
4777 msleep(1); 4777 msleep(1);
4778 count++; 4778 count++;
4779 } 4779 }
4780 } else { 4780 } else {
4781 while (--cntdn) { 4781 while (--cntdn) {
4782 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4782 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4783 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 4783 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4784 break; 4784 break;
4785 udelay (1000); 4785 udelay (1000);
4786 count++; 4786 count++;
4787 } 4787 }
4788 } 4788 }
4789 4789
4790 if (cntdn) { 4790 if (cntdn) {
4791 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n", 4791 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4792 ioc->name, count, howlong)); 4792 ioc->name, count, howlong));
4793 return count; 4793 return count;
4794 } 4794 }
4795 4795
4796 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n", 4796 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4797 ioc->name, count, intstat); 4797 ioc->name, count, intstat);
4798 return -1; 4798 return -1;
4799 } 4799 }
4800 4800
4801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4802 /** 4802 /**
4803 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply. 4803 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4804 * @ioc: Pointer to MPT_ADAPTER structure 4804 * @ioc: Pointer to MPT_ADAPTER structure
4805 * @howlong: How long to wait (in seconds) 4805 * @howlong: How long to wait (in seconds)
4806 * @sleepFlag: Specifies whether the process can sleep 4806 * @sleepFlag: Specifies whether the process can sleep
4807 * 4807 *
4808 * This routine polls the IOC for a handshake reply, 16 bits at a time. 4808 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4809 * Reply is cached to IOC private area large enough to hold a maximum 4809 * Reply is cached to IOC private area large enough to hold a maximum
4810 * of 128 bytes of reply data. 4810 * of 128 bytes of reply data.
4811 * 4811 *
4812 * Returns a negative value on failure, else size of reply in WORDS. 4812 * Returns a negative value on failure, else size of reply in WORDS.
4813 */ 4813 */
4814 static int 4814 static int
4815 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4815 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4816 { 4816 {
4817 int u16cnt = 0; 4817 int u16cnt = 0;
4818 int failcnt = 0; 4818 int failcnt = 0;
4819 int t; 4819 int t;
4820 u16 *hs_reply = ioc->hs_reply; 4820 u16 *hs_reply = ioc->hs_reply;
4821 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply; 4821 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4822 u16 hword; 4822 u16 hword;
4823 4823
4824 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0; 4824 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4825 4825
4826 /* 4826 /*
4827 * Get first two u16's so we can look at IOC's intended reply MsgLength 4827 * Get first two u16's so we can look at IOC's intended reply MsgLength
4828 */ 4828 */
4829 u16cnt=0; 4829 u16cnt=0;
4830 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) { 4830 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4831 failcnt++; 4831 failcnt++;
4832 } else { 4832 } else {
4833 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4833 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4834 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4834 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4835 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4835 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4836 failcnt++; 4836 failcnt++;
4837 else { 4837 else {
4838 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4838 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4839 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4839 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4840 } 4840 }
4841 } 4841 }
4842 4842
4843 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n", 4843 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4844 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply), 4844 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4845 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); 4845 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4846 4846
4847 /* 4847 /*
4848 * If no error (and IOC said MsgLength is > 0), piece together 4848 * If no error (and IOC said MsgLength is > 0), piece together
4849 * reply 16 bits at a time. 4849 * reply 16 bits at a time.
4850 */ 4850 */
4851 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) { 4851 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4852 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4852 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4853 failcnt++; 4853 failcnt++;
4854 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4854 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4855 /* don't overflow our IOC hs_reply[] buffer! */ 4855 /* don't overflow our IOC hs_reply[] buffer! */
4856 if (u16cnt < ARRAY_SIZE(ioc->hs_reply)) 4856 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4857 hs_reply[u16cnt] = hword; 4857 hs_reply[u16cnt] = hword;
4858 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4858 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4859 } 4859 }
4860 4860
4861 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4861 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4862 failcnt++; 4862 failcnt++;
4863 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4863 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4864 4864
4865 if (failcnt) { 4865 if (failcnt) {
4866 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n", 4866 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4867 ioc->name); 4867 ioc->name);
4868 return -failcnt; 4868 return -failcnt;
4869 } 4869 }
4870 #if 0 4870 #if 0
4871 else if (u16cnt != (2 * mptReply->MsgLength)) { 4871 else if (u16cnt != (2 * mptReply->MsgLength)) {
4872 return -101; 4872 return -101;
4873 } 4873 }
4874 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 4874 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4875 return -102; 4875 return -102;
4876 } 4876 }
4877 #endif 4877 #endif
4878 4878
4879 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name)); 4879 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4880 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply); 4880 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4881 4881
4882 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n", 4882 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4883 ioc->name, t, u16cnt/2)); 4883 ioc->name, t, u16cnt/2));
4884 return u16cnt/2; 4884 return u16cnt/2;
4885 } 4885 }
4886 4886
4887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4888 /** 4888 /**
4889 * GetLanConfigPages - Fetch LANConfig pages. 4889 * GetLanConfigPages - Fetch LANConfig pages.
4890 * @ioc: Pointer to MPT_ADAPTER structure 4890 * @ioc: Pointer to MPT_ADAPTER structure
4891 * 4891 *
4892 * Return: 0 for success 4892 * Return: 0 for success
4893 * -ENOMEM if no memory available 4893 * -ENOMEM if no memory available
4894 * -EPERM if not allowed due to ISR context 4894 * -EPERM if not allowed due to ISR context
4895 * -EAGAIN if no msg frames currently available 4895 * -EAGAIN if no msg frames currently available
4896 * -EFAULT for non-successful reply or no reply (timeout) 4896 * -EFAULT for non-successful reply or no reply (timeout)
4897 */ 4897 */
4898 static int 4898 static int
4899 GetLanConfigPages(MPT_ADAPTER *ioc) 4899 GetLanConfigPages(MPT_ADAPTER *ioc)
4900 { 4900 {
4901 ConfigPageHeader_t hdr; 4901 ConfigPageHeader_t hdr;
4902 CONFIGPARMS cfg; 4902 CONFIGPARMS cfg;
4903 LANPage0_t *ppage0_alloc; 4903 LANPage0_t *ppage0_alloc;
4904 dma_addr_t page0_dma; 4904 dma_addr_t page0_dma;
4905 LANPage1_t *ppage1_alloc; 4905 LANPage1_t *ppage1_alloc;
4906 dma_addr_t page1_dma; 4906 dma_addr_t page1_dma;
4907 int rc = 0; 4907 int rc = 0;
4908 int data_sz; 4908 int data_sz;
4909 int copy_sz; 4909 int copy_sz;
4910 4910
4911 /* Get LAN Page 0 header */ 4911 /* Get LAN Page 0 header */
4912 hdr.PageVersion = 0; 4912 hdr.PageVersion = 0;
4913 hdr.PageLength = 0; 4913 hdr.PageLength = 0;
4914 hdr.PageNumber = 0; 4914 hdr.PageNumber = 0;
4915 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; 4915 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4916 cfg.cfghdr.hdr = &hdr; 4916 cfg.cfghdr.hdr = &hdr;
4917 cfg.physAddr = -1; 4917 cfg.physAddr = -1;
4918 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4918 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4919 cfg.dir = 0; 4919 cfg.dir = 0;
4920 cfg.pageAddr = 0; 4920 cfg.pageAddr = 0;
4921 cfg.timeout = 0; 4921 cfg.timeout = 0;
4922 4922
4923 if ((rc = mpt_config(ioc, &cfg)) != 0) 4923 if ((rc = mpt_config(ioc, &cfg)) != 0)
4924 return rc; 4924 return rc;
4925 4925
4926 if (hdr.PageLength > 0) { 4926 if (hdr.PageLength > 0) {
4927 data_sz = hdr.PageLength * 4; 4927 data_sz = hdr.PageLength * 4;
4928 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); 4928 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4929 rc = -ENOMEM; 4929 rc = -ENOMEM;
4930 if (ppage0_alloc) { 4930 if (ppage0_alloc) {
4931 memset((u8 *)ppage0_alloc, 0, data_sz); 4931 memset((u8 *)ppage0_alloc, 0, data_sz);
4932 cfg.physAddr = page0_dma; 4932 cfg.physAddr = page0_dma;
4933 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4933 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4934 4934
4935 if ((rc = mpt_config(ioc, &cfg)) == 0) { 4935 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4936 /* save the data */ 4936 /* save the data */
4937 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz); 4937 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4938 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz); 4938 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4939 4939
4940 } 4940 }
4941 4941
4942 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); 4942 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4943 4943
4944 /* FIXME! 4944 /* FIXME!
4945 * Normalize endianness of structure data, 4945 * Normalize endianness of structure data,
4946 * by byte-swapping all > 1 byte fields! 4946 * by byte-swapping all > 1 byte fields!
4947 */ 4947 */
4948 4948
4949 } 4949 }
4950 4950
4951 if (rc) 4951 if (rc)
4952 return rc; 4952 return rc;
4953 } 4953 }
4954 4954
4955 /* Get LAN Page 1 header */ 4955 /* Get LAN Page 1 header */
4956 hdr.PageVersion = 0; 4956 hdr.PageVersion = 0;
4957 hdr.PageLength = 0; 4957 hdr.PageLength = 0;
4958 hdr.PageNumber = 1; 4958 hdr.PageNumber = 1;
4959 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; 4959 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4960 cfg.cfghdr.hdr = &hdr; 4960 cfg.cfghdr.hdr = &hdr;
4961 cfg.physAddr = -1; 4961 cfg.physAddr = -1;
4962 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4962 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4963 cfg.dir = 0; 4963 cfg.dir = 0;
4964 cfg.pageAddr = 0; 4964 cfg.pageAddr = 0;
4965 4965
4966 if ((rc = mpt_config(ioc, &cfg)) != 0) 4966 if ((rc = mpt_config(ioc, &cfg)) != 0)
4967 return rc; 4967 return rc;
4968 4968
4969 if (hdr.PageLength == 0) 4969 if (hdr.PageLength == 0)
4970 return 0; 4970 return 0;
4971 4971
4972 data_sz = hdr.PageLength * 4; 4972 data_sz = hdr.PageLength * 4;
4973 rc = -ENOMEM; 4973 rc = -ENOMEM;
4974 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma); 4974 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4975 if (ppage1_alloc) { 4975 if (ppage1_alloc) {
4976 memset((u8 *)ppage1_alloc, 0, data_sz); 4976 memset((u8 *)ppage1_alloc, 0, data_sz);
4977 cfg.physAddr = page1_dma; 4977 cfg.physAddr = page1_dma;
4978 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4978 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4979 4979
4980 if ((rc = mpt_config(ioc, &cfg)) == 0) { 4980 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4981 /* save the data */ 4981 /* save the data */
4982 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz); 4982 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4983 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz); 4983 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4984 } 4984 }
4985 4985
4986 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma); 4986 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4987 4987
4988 /* FIXME! 4988 /* FIXME!
4989 * Normalize endianness of structure data, 4989 * Normalize endianness of structure data,
4990 * by byte-swapping all > 1 byte fields! 4990 * by byte-swapping all > 1 byte fields!
4991 */ 4991 */
4992 4992
4993 } 4993 }
4994 4994
4995 return rc; 4995 return rc;
4996 } 4996 }
4997 4997
4998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4999 /** 4999 /**
5000 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table 5000 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5001 * @ioc: Pointer to MPT_ADAPTER structure 5001 * @ioc: Pointer to MPT_ADAPTER structure
5002 * @persist_opcode: see below 5002 * @persist_opcode: see below
5003 * 5003 *
5004 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for 5004 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5005 * devices not currently present. 5005 * devices not currently present.
5006 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings 5006 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5007 * 5007 *
5008 * NOTE: Don't use not this function during interrupt time. 5008 * NOTE: Don't use not this function during interrupt time.
5009 * 5009 *
5010 * Returns 0 for success, non-zero error 5010 * Returns 0 for success, non-zero error
5011 */ 5011 */
5012 5012
5013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5014 int 5014 int
5015 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) 5015 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5016 { 5016 {
5017 SasIoUnitControlRequest_t *sasIoUnitCntrReq; 5017 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5018 SasIoUnitControlReply_t *sasIoUnitCntrReply; 5018 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5019 MPT_FRAME_HDR *mf = NULL; 5019 MPT_FRAME_HDR *mf = NULL;
5020 MPIHeader_t *mpi_hdr; 5020 MPIHeader_t *mpi_hdr;
5021 int ret = 0; 5021 int ret = 0;
5022 unsigned long timeleft; 5022 unsigned long timeleft;
5023 5023
5024 mutex_lock(&ioc->mptbase_cmds.mutex); 5024 mutex_lock(&ioc->mptbase_cmds.mutex);
5025 5025
5026 /* init the internal cmd struct */ 5026 /* init the internal cmd struct */
5027 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE); 5027 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5028 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status) 5028 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5029 5029
5030 /* insure garbage is not sent to fw */ 5030 /* insure garbage is not sent to fw */
5031 switch(persist_opcode) { 5031 switch(persist_opcode) {
5032 5032
5033 case MPI_SAS_OP_CLEAR_NOT_PRESENT: 5033 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5034 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT: 5034 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5035 break; 5035 break;
5036 5036
5037 default: 5037 default:
5038 ret = -1; 5038 ret = -1;
5039 goto out; 5039 goto out;
5040 } 5040 }
5041 5041
5042 printk(KERN_DEBUG "%s: persist_opcode=%x\n", 5042 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5043 __func__, persist_opcode); 5043 __func__, persist_opcode);
5044 5044
5045 /* Get a MF for this command. 5045 /* Get a MF for this command.
5046 */ 5046 */
5047 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 5047 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5048 printk(KERN_DEBUG "%s: no msg frames!\n", __func__); 5048 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5049 ret = -1; 5049 ret = -1;
5050 goto out; 5050 goto out;
5051 } 5051 }
5052 5052
5053 mpi_hdr = (MPIHeader_t *) mf; 5053 mpi_hdr = (MPIHeader_t *) mf;
5054 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf; 5054 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5055 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t)); 5055 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5056 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL; 5056 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5057 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext; 5057 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5058 sasIoUnitCntrReq->Operation = persist_opcode; 5058 sasIoUnitCntrReq->Operation = persist_opcode;
5059 5059
5060 mpt_put_msg_frame(mpt_base_index, ioc, mf); 5060 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5061 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ); 5061 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5062 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { 5062 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5063 ret = -ETIME; 5063 ret = -ETIME;
5064 printk(KERN_DEBUG "%s: failed\n", __func__); 5064 printk(KERN_DEBUG "%s: failed\n", __func__);
5065 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) 5065 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5066 goto out; 5066 goto out;
5067 if (!timeleft) { 5067 if (!timeleft) {
5068 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n", 5068 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
5069 ioc->name, __func__); 5069 ioc->name, __func__);
5070 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); 5070 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5071 mpt_free_msg_frame(ioc, mf); 5071 mpt_free_msg_frame(ioc, mf);
5072 } 5072 }
5073 goto out; 5073 goto out;
5074 } 5074 }
5075 5075
5076 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { 5076 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5077 ret = -1; 5077 ret = -1;
5078 goto out; 5078 goto out;
5079 } 5079 }
5080 5080
5081 sasIoUnitCntrReply = 5081 sasIoUnitCntrReply =
5082 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply; 5082 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5083 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { 5083 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5084 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", 5084 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5085 __func__, sasIoUnitCntrReply->IOCStatus, 5085 __func__, sasIoUnitCntrReply->IOCStatus,
5086 sasIoUnitCntrReply->IOCLogInfo); 5086 sasIoUnitCntrReply->IOCLogInfo);
5087 printk(KERN_DEBUG "%s: failed\n", __func__); 5087 printk(KERN_DEBUG "%s: failed\n", __func__);
5088 ret = -1; 5088 ret = -1;
5089 } else 5089 } else
5090 printk(KERN_DEBUG "%s: success\n", __func__); 5090 printk(KERN_DEBUG "%s: success\n", __func__);
5091 out: 5091 out:
5092 5092
5093 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status) 5093 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5094 mutex_unlock(&ioc->mptbase_cmds.mutex); 5094 mutex_unlock(&ioc->mptbase_cmds.mutex);
5095 return ret; 5095 return ret;
5096 } 5096 }
5097 5097
5098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5099 5099
5100 static void 5100 static void
5101 mptbase_raid_process_event_data(MPT_ADAPTER *ioc, 5101 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5102 MpiEventDataRaid_t * pRaidEventData) 5102 MpiEventDataRaid_t * pRaidEventData)
5103 { 5103 {
5104 int volume; 5104 int volume;
5105 int reason; 5105 int reason;
5106 int disk; 5106 int disk;
5107 int status; 5107 int status;
5108 int flags; 5108 int flags;
5109 int state; 5109 int state;
5110 5110
5111 volume = pRaidEventData->VolumeID; 5111 volume = pRaidEventData->VolumeID;
5112 reason = pRaidEventData->ReasonCode; 5112 reason = pRaidEventData->ReasonCode;
5113 disk = pRaidEventData->PhysDiskNum; 5113 disk = pRaidEventData->PhysDiskNum;
5114 status = le32_to_cpu(pRaidEventData->SettingsStatus); 5114 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5115 flags = (status >> 0) & 0xff; 5115 flags = (status >> 0) & 0xff;
5116 state = (status >> 8) & 0xff; 5116 state = (status >> 8) & 0xff;
5117 5117
5118 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { 5118 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5119 return; 5119 return;
5120 } 5120 }
5121 5121
5122 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && 5122 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5123 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || 5123 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5124 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { 5124 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5125 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n", 5125 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5126 ioc->name, disk, volume); 5126 ioc->name, disk, volume);
5127 } else { 5127 } else {
5128 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", 5128 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5129 ioc->name, volume); 5129 ioc->name, volume);
5130 } 5130 }
5131 5131
5132 switch(reason) { 5132 switch(reason) {
5133 case MPI_EVENT_RAID_RC_VOLUME_CREATED: 5133 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5134 printk(MYIOC_s_INFO_FMT " volume has been created\n", 5134 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5135 ioc->name); 5135 ioc->name);
5136 break; 5136 break;
5137 5137
5138 case MPI_EVENT_RAID_RC_VOLUME_DELETED: 5138 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5139 5139
5140 printk(MYIOC_s_INFO_FMT " volume has been deleted\n", 5140 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5141 ioc->name); 5141 ioc->name);
5142 break; 5142 break;
5143 5143
5144 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED: 5144 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5145 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n", 5145 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5146 ioc->name); 5146 ioc->name);
5147 break; 5147 break;
5148 5148
5149 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: 5149 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5150 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n", 5150 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5151 ioc->name, 5151 ioc->name,
5152 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL 5152 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5153 ? "optimal" 5153 ? "optimal"
5154 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED 5154 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5155 ? "degraded" 5155 ? "degraded"
5156 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED 5156 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5157 ? "failed" 5157 ? "failed"
5158 : "state unknown", 5158 : "state unknown",
5159 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED 5159 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5160 ? ", enabled" : "", 5160 ? ", enabled" : "",
5161 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED 5161 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5162 ? ", quiesced" : "", 5162 ? ", quiesced" : "",
5163 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 5163 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5164 ? ", resync in progress" : "" ); 5164 ? ", resync in progress" : "" );
5165 break; 5165 break;
5166 5166
5167 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED: 5167 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5168 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n", 5168 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5169 ioc->name, disk); 5169 ioc->name, disk);
5170 break; 5170 break;
5171 5171
5172 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: 5172 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5173 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n", 5173 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5174 ioc->name); 5174 ioc->name);
5175 break; 5175 break;
5176 5176
5177 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: 5177 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5178 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n", 5178 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5179 ioc->name); 5179 ioc->name);
5180 break; 5180 break;
5181 5181
5182 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED: 5182 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5183 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n", 5183 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5184 ioc->name); 5184 ioc->name);
5185 break; 5185 break;
5186 5186
5187 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: 5187 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5188 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n", 5188 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5189 ioc->name, 5189 ioc->name,
5190 state == MPI_PHYSDISK0_STATUS_ONLINE 5190 state == MPI_PHYSDISK0_STATUS_ONLINE
5191 ? "online" 5191 ? "online"
5192 : state == MPI_PHYSDISK0_STATUS_MISSING 5192 : state == MPI_PHYSDISK0_STATUS_MISSING
5193 ? "missing" 5193 ? "missing"
5194 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE 5194 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5195 ? "not compatible" 5195 ? "not compatible"
5196 : state == MPI_PHYSDISK0_STATUS_FAILED 5196 : state == MPI_PHYSDISK0_STATUS_FAILED
5197 ? "failed" 5197 ? "failed"
5198 : state == MPI_PHYSDISK0_STATUS_INITIALIZING 5198 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5199 ? "initializing" 5199 ? "initializing"
5200 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED 5200 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5201 ? "offline requested" 5201 ? "offline requested"
5202 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED 5202 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5203 ? "failed requested" 5203 ? "failed requested"
5204 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE 5204 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5205 ? "offline" 5205 ? "offline"
5206 : "state unknown", 5206 : "state unknown",
5207 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 5207 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5208 ? ", out of sync" : "", 5208 ? ", out of sync" : "",
5209 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED 5209 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5210 ? ", quiesced" : "" ); 5210 ? ", quiesced" : "" );
5211 break; 5211 break;
5212 5212
5213 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED: 5213 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5214 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n", 5214 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5215 ioc->name, disk); 5215 ioc->name, disk);
5216 break; 5216 break;
5217 5217
5218 case MPI_EVENT_RAID_RC_SMART_DATA: 5218 case MPI_EVENT_RAID_RC_SMART_DATA:
5219 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n", 5219 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5220 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ); 5220 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5221 break; 5221 break;
5222 5222
5223 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED: 5223 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5224 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n", 5224 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5225 ioc->name, disk); 5225 ioc->name, disk);
5226 break; 5226 break;
5227 } 5227 }
5228 } 5228 }
5229 5229
5230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5231 /** 5231 /**
5232 * GetIoUnitPage2 - Retrieve BIOS version and boot order information. 5232 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5233 * @ioc: Pointer to MPT_ADAPTER structure 5233 * @ioc: Pointer to MPT_ADAPTER structure
5234 * 5234 *
5235 * Returns: 0 for success 5235 * Returns: 0 for success
5236 * -ENOMEM if no memory available 5236 * -ENOMEM if no memory available
5237 * -EPERM if not allowed due to ISR context 5237 * -EPERM if not allowed due to ISR context
5238 * -EAGAIN if no msg frames currently available 5238 * -EAGAIN if no msg frames currently available
5239 * -EFAULT for non-successful reply or no reply (timeout) 5239 * -EFAULT for non-successful reply or no reply (timeout)
5240 */ 5240 */
5241 static int 5241 static int
5242 GetIoUnitPage2(MPT_ADAPTER *ioc) 5242 GetIoUnitPage2(MPT_ADAPTER *ioc)
5243 { 5243 {
5244 ConfigPageHeader_t hdr; 5244 ConfigPageHeader_t hdr;
5245 CONFIGPARMS cfg; 5245 CONFIGPARMS cfg;
5246 IOUnitPage2_t *ppage_alloc; 5246 IOUnitPage2_t *ppage_alloc;
5247 dma_addr_t page_dma; 5247 dma_addr_t page_dma;
5248 int data_sz; 5248 int data_sz;
5249 int rc; 5249 int rc;
5250 5250
5251 /* Get the page header */ 5251 /* Get the page header */
5252 hdr.PageVersion = 0; 5252 hdr.PageVersion = 0;
5253 hdr.PageLength = 0; 5253 hdr.PageLength = 0;
5254 hdr.PageNumber = 2; 5254 hdr.PageNumber = 2;
5255 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT; 5255 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5256 cfg.cfghdr.hdr = &hdr; 5256 cfg.cfghdr.hdr = &hdr;
5257 cfg.physAddr = -1; 5257 cfg.physAddr = -1;
5258 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5258 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5259 cfg.dir = 0; 5259 cfg.dir = 0;
5260 cfg.pageAddr = 0; 5260 cfg.pageAddr = 0;
5261 cfg.timeout = 0; 5261 cfg.timeout = 0;
5262 5262
5263 if ((rc = mpt_config(ioc, &cfg)) != 0) 5263 if ((rc = mpt_config(ioc, &cfg)) != 0)
5264 return rc; 5264 return rc;
5265 5265
5266 if (hdr.PageLength == 0) 5266 if (hdr.PageLength == 0)
5267 return 0; 5267 return 0;
5268 5268
5269 /* Read the config page */ 5269 /* Read the config page */
5270 data_sz = hdr.PageLength * 4; 5270 data_sz = hdr.PageLength * 4;
5271 rc = -ENOMEM; 5271 rc = -ENOMEM;
5272 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma); 5272 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5273 if (ppage_alloc) { 5273 if (ppage_alloc) {
5274 memset((u8 *)ppage_alloc, 0, data_sz); 5274 memset((u8 *)ppage_alloc, 0, data_sz);
5275 cfg.physAddr = page_dma; 5275 cfg.physAddr = page_dma;
5276 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5276 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5277 5277
5278 /* If Good, save data */ 5278 /* If Good, save data */
5279 if ((rc = mpt_config(ioc, &cfg)) == 0) 5279 if ((rc = mpt_config(ioc, &cfg)) == 0)
5280 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion); 5280 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5281 5281
5282 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma); 5282 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5283 } 5283 }
5284 5284
5285 return rc; 5285 return rc;
5286 } 5286 }
5287 5287
5288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5289 /** 5289 /**
5290 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2 5290 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5291 * @ioc: Pointer to a Adapter Strucutre 5291 * @ioc: Pointer to a Adapter Strucutre
5292 * @portnum: IOC port number 5292 * @portnum: IOC port number
5293 * 5293 *
5294 * Return: -EFAULT if read of config page header fails 5294 * Return: -EFAULT if read of config page header fails
5295 * or if no nvram 5295 * or if no nvram
5296 * If read of SCSI Port Page 0 fails, 5296 * If read of SCSI Port Page 0 fails,
5297 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF) 5297 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5298 * Adapter settings: async, narrow 5298 * Adapter settings: async, narrow
5299 * Return 1 5299 * Return 1
5300 * If read of SCSI Port Page 2 fails, 5300 * If read of SCSI Port Page 2 fails,
5301 * Adapter settings valid 5301 * Adapter settings valid
5302 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF) 5302 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5303 * Return 1 5303 * Return 1
5304 * Else 5304 * Else
5305 * Both valid 5305 * Both valid
5306 * Return 0 5306 * Return 0
5307 * CHECK - what type of locking mechanisms should be used???? 5307 * CHECK - what type of locking mechanisms should be used????
5308 */ 5308 */
5309 static int 5309 static int
5310 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) 5310 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5311 { 5311 {
5312 u8 *pbuf; 5312 u8 *pbuf;
5313 dma_addr_t buf_dma; 5313 dma_addr_t buf_dma;
5314 CONFIGPARMS cfg; 5314 CONFIGPARMS cfg;
5315 ConfigPageHeader_t header; 5315 ConfigPageHeader_t header;
5316 int ii; 5316 int ii;
5317 int data, rc = 0; 5317 int data, rc = 0;
5318 5318
5319 /* Allocate memory 5319 /* Allocate memory
5320 */ 5320 */
5321 if (!ioc->spi_data.nvram) { 5321 if (!ioc->spi_data.nvram) {
5322 int sz; 5322 int sz;
5323 u8 *mem; 5323 u8 *mem;
5324 sz = MPT_MAX_SCSI_DEVICES * sizeof(int); 5324 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5325 mem = kmalloc(sz, GFP_ATOMIC); 5325 mem = kmalloc(sz, GFP_ATOMIC);
5326 if (mem == NULL) 5326 if (mem == NULL)
5327 return -EFAULT; 5327 return -EFAULT;
5328 5328
5329 ioc->spi_data.nvram = (int *) mem; 5329 ioc->spi_data.nvram = (int *) mem;
5330 5330
5331 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n", 5331 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5332 ioc->name, ioc->spi_data.nvram, sz)); 5332 ioc->name, ioc->spi_data.nvram, sz));
5333 } 5333 }
5334 5334
5335 /* Invalidate NVRAM information 5335 /* Invalidate NVRAM information
5336 */ 5336 */
5337 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5337 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5338 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID; 5338 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5339 } 5339 }
5340 5340
5341 /* Read SPP0 header, allocate memory, then read page. 5341 /* Read SPP0 header, allocate memory, then read page.
5342 */ 5342 */
5343 header.PageVersion = 0; 5343 header.PageVersion = 0;
5344 header.PageLength = 0; 5344 header.PageLength = 0;
5345 header.PageNumber = 0; 5345 header.PageNumber = 0;
5346 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; 5346 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5347 cfg.cfghdr.hdr = &header; 5347 cfg.cfghdr.hdr = &header;
5348 cfg.physAddr = -1; 5348 cfg.physAddr = -1;
5349 cfg.pageAddr = portnum; 5349 cfg.pageAddr = portnum;
5350 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5350 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5351 cfg.dir = 0; 5351 cfg.dir = 0;
5352 cfg.timeout = 0; /* use default */ 5352 cfg.timeout = 0; /* use default */
5353 if (mpt_config(ioc, &cfg) != 0) 5353 if (mpt_config(ioc, &cfg) != 0)
5354 return -EFAULT; 5354 return -EFAULT;
5355 5355
5356 if (header.PageLength > 0) { 5356 if (header.PageLength > 0) {
5357 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma); 5357 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5358 if (pbuf) { 5358 if (pbuf) {
5359 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5359 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5360 cfg.physAddr = buf_dma; 5360 cfg.physAddr = buf_dma;
5361 if (mpt_config(ioc, &cfg) != 0) { 5361 if (mpt_config(ioc, &cfg) != 0) {
5362 ioc->spi_data.maxBusWidth = MPT_NARROW; 5362 ioc->spi_data.maxBusWidth = MPT_NARROW;
5363 ioc->spi_data.maxSyncOffset = 0; 5363 ioc->spi_data.maxSyncOffset = 0;
5364 ioc->spi_data.minSyncFactor = MPT_ASYNC; 5364 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5365 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN; 5365 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5366 rc = 1; 5366 rc = 1;
5367 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5367 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5368 "Unable to read PortPage0 minSyncFactor=%x\n", 5368 "Unable to read PortPage0 minSyncFactor=%x\n",
5369 ioc->name, ioc->spi_data.minSyncFactor)); 5369 ioc->name, ioc->spi_data.minSyncFactor));
5370 } else { 5370 } else {
5371 /* Save the Port Page 0 data 5371 /* Save the Port Page 0 data
5372 */ 5372 */
5373 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf; 5373 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5374 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities); 5374 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5375 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface); 5375 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5376 5376
5377 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) { 5377 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5378 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS; 5378 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5379 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5379 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5380 "noQas due to Capabilities=%x\n", 5380 "noQas due to Capabilities=%x\n",
5381 ioc->name, pPP0->Capabilities)); 5381 ioc->name, pPP0->Capabilities));
5382 } 5382 }
5383 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0; 5383 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5384 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK; 5384 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5385 if (data) { 5385 if (data) {
5386 ioc->spi_data.maxSyncOffset = (u8) (data >> 16); 5386 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5387 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK; 5387 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5388 ioc->spi_data.minSyncFactor = (u8) (data >> 8); 5388 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5389 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5389 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5390 "PortPage0 minSyncFactor=%x\n", 5390 "PortPage0 minSyncFactor=%x\n",
5391 ioc->name, ioc->spi_data.minSyncFactor)); 5391 ioc->name, ioc->spi_data.minSyncFactor));
5392 } else { 5392 } else {
5393 ioc->spi_data.maxSyncOffset = 0; 5393 ioc->spi_data.maxSyncOffset = 0;
5394 ioc->spi_data.minSyncFactor = MPT_ASYNC; 5394 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5395 } 5395 }
5396 5396
5397 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK; 5397 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5398 5398
5399 /* Update the minSyncFactor based on bus type. 5399 /* Update the minSyncFactor based on bus type.
5400 */ 5400 */
5401 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) || 5401 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5402 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) { 5402 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5403 5403
5404 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) { 5404 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5405 ioc->spi_data.minSyncFactor = MPT_ULTRA; 5405 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5406 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5406 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5407 "HVD or SE detected, minSyncFactor=%x\n", 5407 "HVD or SE detected, minSyncFactor=%x\n",
5408 ioc->name, ioc->spi_data.minSyncFactor)); 5408 ioc->name, ioc->spi_data.minSyncFactor));
5409 } 5409 }
5410 } 5410 }
5411 } 5411 }
5412 if (pbuf) { 5412 if (pbuf) {
5413 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); 5413 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5414 } 5414 }
5415 } 5415 }
5416 } 5416 }
5417 5417
5418 /* SCSI Port Page 2 - Read the header then the page. 5418 /* SCSI Port Page 2 - Read the header then the page.
5419 */ 5419 */
5420 header.PageVersion = 0; 5420 header.PageVersion = 0;
5421 header.PageLength = 0; 5421 header.PageLength = 0;
5422 header.PageNumber = 2; 5422 header.PageNumber = 2;
5423 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; 5423 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5424 cfg.cfghdr.hdr = &header; 5424 cfg.cfghdr.hdr = &header;
5425 cfg.physAddr = -1; 5425 cfg.physAddr = -1;
5426 cfg.pageAddr = portnum; 5426 cfg.pageAddr = portnum;
5427 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5427 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5428 cfg.dir = 0; 5428 cfg.dir = 0;
5429 if (mpt_config(ioc, &cfg) != 0) 5429 if (mpt_config(ioc, &cfg) != 0)
5430 return -EFAULT; 5430 return -EFAULT;
5431 5431
5432 if (header.PageLength > 0) { 5432 if (header.PageLength > 0) {
5433 /* Allocate memory and read SCSI Port Page 2 5433 /* Allocate memory and read SCSI Port Page 2
5434 */ 5434 */
5435 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma); 5435 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5436 if (pbuf) { 5436 if (pbuf) {
5437 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM; 5437 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5438 cfg.physAddr = buf_dma; 5438 cfg.physAddr = buf_dma;
5439 if (mpt_config(ioc, &cfg) != 0) { 5439 if (mpt_config(ioc, &cfg) != 0) {
5440 /* Nvram data is left with INVALID mark 5440 /* Nvram data is left with INVALID mark
5441 */ 5441 */
5442 rc = 1; 5442 rc = 1;
5443 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) { 5443 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5444 5444
5445 /* This is an ATTO adapter, read Page2 accordingly 5445 /* This is an ATTO adapter, read Page2 accordingly
5446 */ 5446 */
5447 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf; 5447 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5448 ATTODeviceInfo_t *pdevice = NULL; 5448 ATTODeviceInfo_t *pdevice = NULL;
5449 u16 ATTOFlags; 5449 u16 ATTOFlags;
5450 5450
5451 /* Save the Port Page 2 data 5451 /* Save the Port Page 2 data
5452 * (reformat into a 32bit quantity) 5452 * (reformat into a 32bit quantity)
5453 */ 5453 */
5454 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5454 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5455 pdevice = &pPP2->DeviceSettings[ii]; 5455 pdevice = &pPP2->DeviceSettings[ii];
5456 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags); 5456 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5457 data = 0; 5457 data = 0;
5458 5458
5459 /* Translate ATTO device flags to LSI format 5459 /* Translate ATTO device flags to LSI format
5460 */ 5460 */
5461 if (ATTOFlags & ATTOFLAG_DISC) 5461 if (ATTOFlags & ATTOFLAG_DISC)
5462 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE); 5462 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5463 if (ATTOFlags & ATTOFLAG_ID_ENB) 5463 if (ATTOFlags & ATTOFLAG_ID_ENB)
5464 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE); 5464 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5465 if (ATTOFlags & ATTOFLAG_LUN_ENB) 5465 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5466 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE); 5466 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5467 if (ATTOFlags & ATTOFLAG_TAGGED) 5467 if (ATTOFlags & ATTOFLAG_TAGGED)
5468 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE); 5468 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5469 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB)) 5469 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5470 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE); 5470 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5471 5471
5472 data = (data << 16) | (pdevice->Period << 8) | 10; 5472 data = (data << 16) | (pdevice->Period << 8) | 10;
5473 ioc->spi_data.nvram[ii] = data; 5473 ioc->spi_data.nvram[ii] = data;
5474 } 5474 }
5475 } else { 5475 } else {
5476 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; 5476 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5477 MpiDeviceInfo_t *pdevice = NULL; 5477 MpiDeviceInfo_t *pdevice = NULL;
5478 5478
5479 /* 5479 /*
5480 * Save "Set to Avoid SCSI Bus Resets" flag 5480 * Save "Set to Avoid SCSI Bus Resets" flag
5481 */ 5481 */
5482 ioc->spi_data.bus_reset = 5482 ioc->spi_data.bus_reset =
5483 (le32_to_cpu(pPP2->PortFlags) & 5483 (le32_to_cpu(pPP2->PortFlags) &
5484 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ? 5484 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5485 0 : 1 ; 5485 0 : 1 ;
5486 5486
5487 /* Save the Port Page 2 data 5487 /* Save the Port Page 2 data
5488 * (reformat into a 32bit quantity) 5488 * (reformat into a 32bit quantity)
5489 */ 5489 */
5490 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK; 5490 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5491 ioc->spi_data.PortFlags = data; 5491 ioc->spi_data.PortFlags = data;
5492 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5492 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5493 pdevice = &pPP2->DeviceSettings[ii]; 5493 pdevice = &pPP2->DeviceSettings[ii];
5494 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) | 5494 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5495 (pdevice->SyncFactor << 8) | pdevice->Timeout; 5495 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5496 ioc->spi_data.nvram[ii] = data; 5496 ioc->spi_data.nvram[ii] = data;
5497 } 5497 }
5498 } 5498 }
5499 5499
5500 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); 5500 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5501 } 5501 }
5502 } 5502 }
5503 5503
5504 /* Update Adapter limits with those from NVRAM 5504 /* Update Adapter limits with those from NVRAM
5505 * Comment: Don't need to do this. Target performance 5505 * Comment: Don't need to do this. Target performance
5506 * parameters will never exceed the adapters limits. 5506 * parameters will never exceed the adapters limits.
5507 */ 5507 */
5508 5508
5509 return rc; 5509 return rc;
5510 } 5510 }
5511 5511
5512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5513 /** 5513 /**
5514 * mpt_readScsiDevicePageHeaders - save version and length of SDP1 5514 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5515 * @ioc: Pointer to a Adapter Strucutre 5515 * @ioc: Pointer to a Adapter Strucutre
5516 * @portnum: IOC port number 5516 * @portnum: IOC port number
5517 * 5517 *
5518 * Return: -EFAULT if read of config page header fails 5518 * Return: -EFAULT if read of config page header fails
5519 * or 0 if success. 5519 * or 0 if success.
5520 */ 5520 */
5521 static int 5521 static int
5522 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) 5522 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5523 { 5523 {
5524 CONFIGPARMS cfg; 5524 CONFIGPARMS cfg;
5525 ConfigPageHeader_t header; 5525 ConfigPageHeader_t header;
5526 5526
5527 /* Read the SCSI Device Page 1 header 5527 /* Read the SCSI Device Page 1 header
5528 */ 5528 */
5529 header.PageVersion = 0; 5529 header.PageVersion = 0;
5530 header.PageLength = 0; 5530 header.PageLength = 0;
5531 header.PageNumber = 1; 5531 header.PageNumber = 1;
5532 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 5532 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5533 cfg.cfghdr.hdr = &header; 5533 cfg.cfghdr.hdr = &header;
5534 cfg.physAddr = -1; 5534 cfg.physAddr = -1;
5535 cfg.pageAddr = portnum; 5535 cfg.pageAddr = portnum;
5536 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5536 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5537 cfg.dir = 0; 5537 cfg.dir = 0;
5538 cfg.timeout = 0; 5538 cfg.timeout = 0;
5539 if (mpt_config(ioc, &cfg) != 0) 5539 if (mpt_config(ioc, &cfg) != 0)
5540 return -EFAULT; 5540 return -EFAULT;
5541 5541
5542 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion; 5542 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5543 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength; 5543 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5544 5544
5545 header.PageVersion = 0; 5545 header.PageVersion = 0;
5546 header.PageLength = 0; 5546 header.PageLength = 0;
5547 header.PageNumber = 0; 5547 header.PageNumber = 0;
5548 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 5548 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5549 if (mpt_config(ioc, &cfg) != 0) 5549 if (mpt_config(ioc, &cfg) != 0)
5550 return -EFAULT; 5550 return -EFAULT;
5551 5551
5552 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion; 5552 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5553 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength; 5553 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5554 5554
5555 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n", 5555 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5556 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length)); 5556 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5557 5557
5558 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n", 5558 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5559 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length)); 5559 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5560 return 0; 5560 return 0;
5561 } 5561 }
5562 5562
5563 /** 5563 /**
5564 * mpt_inactive_raid_list_free - This clears this link list. 5564 * mpt_inactive_raid_list_free - This clears this link list.
5565 * @ioc : pointer to per adapter structure 5565 * @ioc : pointer to per adapter structure
5566 **/ 5566 **/
5567 static void 5567 static void
5568 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) 5568 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5569 { 5569 {
5570 struct inactive_raid_component_info *component_info, *pNext; 5570 struct inactive_raid_component_info *component_info, *pNext;
5571 5571
5572 if (list_empty(&ioc->raid_data.inactive_list)) 5572 if (list_empty(&ioc->raid_data.inactive_list))
5573 return; 5573 return;
5574 5574
5575 mutex_lock(&ioc->raid_data.inactive_list_mutex); 5575 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5576 list_for_each_entry_safe(component_info, pNext, 5576 list_for_each_entry_safe(component_info, pNext,
5577 &ioc->raid_data.inactive_list, list) { 5577 &ioc->raid_data.inactive_list, list) {
5578 list_del(&component_info->list); 5578 list_del(&component_info->list);
5579 kfree(component_info); 5579 kfree(component_info);
5580 } 5580 }
5581 mutex_unlock(&ioc->raid_data.inactive_list_mutex); 5581 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5582 } 5582 }
5583 5583
5584 /** 5584 /**
5585 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume 5585 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5586 * 5586 *
5587 * @ioc : pointer to per adapter structure 5587 * @ioc : pointer to per adapter structure
5588 * @channel : volume channel 5588 * @channel : volume channel
5589 * @id : volume target id 5589 * @id : volume target id
5590 **/ 5590 **/
5591 static void 5591 static void
5592 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) 5592 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5593 { 5593 {
5594 CONFIGPARMS cfg; 5594 CONFIGPARMS cfg;
5595 ConfigPageHeader_t hdr; 5595 ConfigPageHeader_t hdr;
5596 dma_addr_t dma_handle; 5596 dma_addr_t dma_handle;
5597 pRaidVolumePage0_t buffer = NULL; 5597 pRaidVolumePage0_t buffer = NULL;
5598 int i; 5598 int i;
5599 RaidPhysDiskPage0_t phys_disk; 5599 RaidPhysDiskPage0_t phys_disk;
5600 struct inactive_raid_component_info *component_info; 5600 struct inactive_raid_component_info *component_info;
5601 int handle_inactive_volumes; 5601 int handle_inactive_volumes;
5602 5602
5603 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5603 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5604 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5604 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5605 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; 5605 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5606 cfg.pageAddr = (channel << 8) + id; 5606 cfg.pageAddr = (channel << 8) + id;
5607 cfg.cfghdr.hdr = &hdr; 5607 cfg.cfghdr.hdr = &hdr;
5608 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5608 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5609 5609
5610 if (mpt_config(ioc, &cfg) != 0) 5610 if (mpt_config(ioc, &cfg) != 0)
5611 goto out; 5611 goto out;
5612 5612
5613 if (!hdr.PageLength) 5613 if (!hdr.PageLength)
5614 goto out; 5614 goto out;
5615 5615
5616 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5616 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5617 &dma_handle); 5617 &dma_handle);
5618 5618
5619 if (!buffer) 5619 if (!buffer)
5620 goto out; 5620 goto out;
5621 5621
5622 cfg.physAddr = dma_handle; 5622 cfg.physAddr = dma_handle;
5623 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5623 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5624 5624
5625 if (mpt_config(ioc, &cfg) != 0) 5625 if (mpt_config(ioc, &cfg) != 0)
5626 goto out; 5626 goto out;
5627 5627
5628 if (!buffer->NumPhysDisks) 5628 if (!buffer->NumPhysDisks)
5629 goto out; 5629 goto out;
5630 5630
5631 handle_inactive_volumes = 5631 handle_inactive_volumes =
5632 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE || 5632 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5633 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 || 5633 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5634 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED || 5634 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5635 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0; 5635 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5636 5636
5637 if (!handle_inactive_volumes) 5637 if (!handle_inactive_volumes)
5638 goto out; 5638 goto out;
5639 5639
5640 mutex_lock(&ioc->raid_data.inactive_list_mutex); 5640 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5641 for (i = 0; i < buffer->NumPhysDisks; i++) { 5641 for (i = 0; i < buffer->NumPhysDisks; i++) {
5642 if(mpt_raid_phys_disk_pg0(ioc, 5642 if(mpt_raid_phys_disk_pg0(ioc,
5643 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) 5643 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5644 continue; 5644 continue;
5645 5645
5646 if ((component_info = kmalloc(sizeof (*component_info), 5646 if ((component_info = kmalloc(sizeof (*component_info),
5647 GFP_KERNEL)) == NULL) 5647 GFP_KERNEL)) == NULL)
5648 continue; 5648 continue;
5649 5649
5650 component_info->volumeID = id; 5650 component_info->volumeID = id;
5651 component_info->volumeBus = channel; 5651 component_info->volumeBus = channel;
5652 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum; 5652 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5653 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus; 5653 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5654 component_info->d.PhysDiskID = phys_disk.PhysDiskID; 5654 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5655 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC; 5655 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5656 5656
5657 list_add_tail(&component_info->list, 5657 list_add_tail(&component_info->list,
5658 &ioc->raid_data.inactive_list); 5658 &ioc->raid_data.inactive_list);
5659 } 5659 }
5660 mutex_unlock(&ioc->raid_data.inactive_list_mutex); 5660 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5661 5661
5662 out: 5662 out:
5663 if (buffer) 5663 if (buffer)
5664 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5664 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5665 dma_handle); 5665 dma_handle);
5666 } 5666 }
5667 5667
5668 /** 5668 /**
5669 * mpt_raid_phys_disk_pg0 - returns phys disk page zero 5669 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5670 * @ioc: Pointer to a Adapter Structure 5670 * @ioc: Pointer to a Adapter Structure
5671 * @phys_disk_num: io unit unique phys disk num generated by the ioc 5671 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5672 * @phys_disk: requested payload data returned 5672 * @phys_disk: requested payload data returned
5673 * 5673 *
5674 * Return: 5674 * Return:
5675 * 0 on success 5675 * 0 on success
5676 * -EFAULT if read of config page header fails or data pointer not NULL 5676 * -EFAULT if read of config page header fails or data pointer not NULL
5677 * -ENOMEM if pci_alloc failed 5677 * -ENOMEM if pci_alloc failed
5678 **/ 5678 **/
5679 int 5679 int
5680 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, 5680 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5681 RaidPhysDiskPage0_t *phys_disk) 5681 RaidPhysDiskPage0_t *phys_disk)
5682 { 5682 {
5683 CONFIGPARMS cfg; 5683 CONFIGPARMS cfg;
5684 ConfigPageHeader_t hdr; 5684 ConfigPageHeader_t hdr;
5685 dma_addr_t dma_handle; 5685 dma_addr_t dma_handle;
5686 pRaidPhysDiskPage0_t buffer = NULL; 5686 pRaidPhysDiskPage0_t buffer = NULL;
5687 int rc; 5687 int rc;
5688 5688
5689 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5689 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5690 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5690 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5691 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t)); 5691 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5692 5692
5693 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION; 5693 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5694 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5694 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5695 cfg.cfghdr.hdr = &hdr; 5695 cfg.cfghdr.hdr = &hdr;
5696 cfg.physAddr = -1; 5696 cfg.physAddr = -1;
5697 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5697 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5698 5698
5699 if (mpt_config(ioc, &cfg) != 0) { 5699 if (mpt_config(ioc, &cfg) != 0) {
5700 rc = -EFAULT; 5700 rc = -EFAULT;
5701 goto out; 5701 goto out;
5702 } 5702 }
5703 5703
5704 if (!hdr.PageLength) { 5704 if (!hdr.PageLength) {
5705 rc = -EFAULT; 5705 rc = -EFAULT;
5706 goto out; 5706 goto out;
5707 } 5707 }
5708 5708
5709 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5709 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5710 &dma_handle); 5710 &dma_handle);
5711 5711
5712 if (!buffer) { 5712 if (!buffer) {
5713 rc = -ENOMEM; 5713 rc = -ENOMEM;
5714 goto out; 5714 goto out;
5715 } 5715 }
5716 5716
5717 cfg.physAddr = dma_handle; 5717 cfg.physAddr = dma_handle;
5718 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5718 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5719 cfg.pageAddr = phys_disk_num; 5719 cfg.pageAddr = phys_disk_num;
5720 5720
5721 if (mpt_config(ioc, &cfg) != 0) { 5721 if (mpt_config(ioc, &cfg) != 0) {
5722 rc = -EFAULT; 5722 rc = -EFAULT;
5723 goto out; 5723 goto out;
5724 } 5724 }
5725 5725
5726 rc = 0; 5726 rc = 0;
5727 memcpy(phys_disk, buffer, sizeof(*buffer)); 5727 memcpy(phys_disk, buffer, sizeof(*buffer));
5728 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA); 5728 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5729 5729
5730 out: 5730 out:
5731 5731
5732 if (buffer) 5732 if (buffer)
5733 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5733 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5734 dma_handle); 5734 dma_handle);
5735 5735
5736 return rc; 5736 return rc;
5737 } 5737 }
5738 5738
5739 /** 5739 /**
5740 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num 5740 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5741 * @ioc: Pointer to a Adapter Structure 5741 * @ioc: Pointer to a Adapter Structure
5742 * @phys_disk_num: io unit unique phys disk num generated by the ioc 5742 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5743 * 5743 *
5744 * Return: 5744 * Return:
5745 * returns number paths 5745 * returns number paths
5746 **/ 5746 **/
5747 int 5747 int
5748 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num) 5748 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5749 { 5749 {
5750 CONFIGPARMS cfg; 5750 CONFIGPARMS cfg;
5751 ConfigPageHeader_t hdr; 5751 ConfigPageHeader_t hdr;
5752 dma_addr_t dma_handle; 5752 dma_addr_t dma_handle;
5753 pRaidPhysDiskPage1_t buffer = NULL; 5753 pRaidPhysDiskPage1_t buffer = NULL;
5754 int rc; 5754 int rc;
5755 5755
5756 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5756 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5757 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5757 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5758 5758
5759 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION; 5759 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5760 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5760 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5761 hdr.PageNumber = 1; 5761 hdr.PageNumber = 1;
5762 cfg.cfghdr.hdr = &hdr; 5762 cfg.cfghdr.hdr = &hdr;
5763 cfg.physAddr = -1; 5763 cfg.physAddr = -1;
5764 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5764 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5765 5765
5766 if (mpt_config(ioc, &cfg) != 0) { 5766 if (mpt_config(ioc, &cfg) != 0) {
5767 rc = 0; 5767 rc = 0;
5768 goto out; 5768 goto out;
5769 } 5769 }
5770 5770
5771 if (!hdr.PageLength) { 5771 if (!hdr.PageLength) {
5772 rc = 0; 5772 rc = 0;
5773 goto out; 5773 goto out;
5774 } 5774 }
5775 5775
5776 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5776 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5777 &dma_handle); 5777 &dma_handle);
5778 5778
5779 if (!buffer) { 5779 if (!buffer) {
5780 rc = 0; 5780 rc = 0;
5781 goto out; 5781 goto out;
5782 } 5782 }
5783 5783
5784 cfg.physAddr = dma_handle; 5784 cfg.physAddr = dma_handle;
5785 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5785 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5786 cfg.pageAddr = phys_disk_num; 5786 cfg.pageAddr = phys_disk_num;
5787 5787
5788 if (mpt_config(ioc, &cfg) != 0) { 5788 if (mpt_config(ioc, &cfg) != 0) {
5789 rc = 0; 5789 rc = 0;
5790 goto out; 5790 goto out;
5791 } 5791 }
5792 5792
5793 rc = buffer->NumPhysDiskPaths; 5793 rc = buffer->NumPhysDiskPaths;
5794 out: 5794 out:
5795 5795
5796 if (buffer) 5796 if (buffer)
5797 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5797 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5798 dma_handle); 5798 dma_handle);
5799 5799
5800 return rc; 5800 return rc;
5801 } 5801 }
5802 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths); 5802 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5803 5803
5804 /** 5804 /**
5805 * mpt_raid_phys_disk_pg1 - returns phys disk page 1 5805 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5806 * @ioc: Pointer to a Adapter Structure 5806 * @ioc: Pointer to a Adapter Structure
5807 * @phys_disk_num: io unit unique phys disk num generated by the ioc 5807 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5808 * @phys_disk: requested payload data returned 5808 * @phys_disk: requested payload data returned
5809 * 5809 *
5810 * Return: 5810 * Return:
5811 * 0 on success 5811 * 0 on success
5812 * -EFAULT if read of config page header fails or data pointer not NULL 5812 * -EFAULT if read of config page header fails or data pointer not NULL
5813 * -ENOMEM if pci_alloc failed 5813 * -ENOMEM if pci_alloc failed
5814 **/ 5814 **/
5815 int 5815 int
5816 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num, 5816 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5817 RaidPhysDiskPage1_t *phys_disk) 5817 RaidPhysDiskPage1_t *phys_disk)
5818 { 5818 {
5819 CONFIGPARMS cfg; 5819 CONFIGPARMS cfg;
5820 ConfigPageHeader_t hdr; 5820 ConfigPageHeader_t hdr;
5821 dma_addr_t dma_handle; 5821 dma_addr_t dma_handle;
5822 pRaidPhysDiskPage1_t buffer = NULL; 5822 pRaidPhysDiskPage1_t buffer = NULL;
5823 int rc; 5823 int rc;
5824 int i; 5824 int i;
5825 __le64 sas_address; 5825 __le64 sas_address;
5826 5826
5827 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5827 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5828 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5828 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5829 rc = 0; 5829 rc = 0;
5830 5830
5831 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION; 5831 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5832 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5832 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5833 hdr.PageNumber = 1; 5833 hdr.PageNumber = 1;
5834 cfg.cfghdr.hdr = &hdr; 5834 cfg.cfghdr.hdr = &hdr;
5835 cfg.physAddr = -1; 5835 cfg.physAddr = -1;
5836 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5836 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5837 5837
5838 if (mpt_config(ioc, &cfg) != 0) { 5838 if (mpt_config(ioc, &cfg) != 0) {
5839 rc = -EFAULT; 5839 rc = -EFAULT;
5840 goto out; 5840 goto out;
5841 } 5841 }
5842 5842
5843 if (!hdr.PageLength) { 5843 if (!hdr.PageLength) {
5844 rc = -EFAULT; 5844 rc = -EFAULT;
5845 goto out; 5845 goto out;
5846 } 5846 }
5847 5847
5848 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5848 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5849 &dma_handle); 5849 &dma_handle);
5850 5850
5851 if (!buffer) { 5851 if (!buffer) {
5852 rc = -ENOMEM; 5852 rc = -ENOMEM;
5853 goto out; 5853 goto out;
5854 } 5854 }
5855 5855
5856 cfg.physAddr = dma_handle; 5856 cfg.physAddr = dma_handle;
5857 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5857 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5858 cfg.pageAddr = phys_disk_num; 5858 cfg.pageAddr = phys_disk_num;
5859 5859
5860 if (mpt_config(ioc, &cfg) != 0) { 5860 if (mpt_config(ioc, &cfg) != 0) {
5861 rc = -EFAULT; 5861 rc = -EFAULT;
5862 goto out; 5862 goto out;
5863 } 5863 }
5864 5864
5865 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths; 5865 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5866 phys_disk->PhysDiskNum = phys_disk_num; 5866 phys_disk->PhysDiskNum = phys_disk_num;
5867 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) { 5867 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5868 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID; 5868 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5869 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus; 5869 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5870 phys_disk->Path[i].OwnerIdentifier = 5870 phys_disk->Path[i].OwnerIdentifier =
5871 buffer->Path[i].OwnerIdentifier; 5871 buffer->Path[i].OwnerIdentifier;
5872 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags); 5872 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5873 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64)); 5873 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5874 sas_address = le64_to_cpu(sas_address); 5874 sas_address = le64_to_cpu(sas_address);
5875 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64)); 5875 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5876 memcpy(&sas_address, 5876 memcpy(&sas_address,
5877 &buffer->Path[i].OwnerWWID, sizeof(__le64)); 5877 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5878 sas_address = le64_to_cpu(sas_address); 5878 sas_address = le64_to_cpu(sas_address);
5879 memcpy(&phys_disk->Path[i].OwnerWWID, 5879 memcpy(&phys_disk->Path[i].OwnerWWID,
5880 &sas_address, sizeof(__le64)); 5880 &sas_address, sizeof(__le64));
5881 } 5881 }
5882 5882
5883 out: 5883 out:
5884 5884
5885 if (buffer) 5885 if (buffer)
5886 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5886 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5887 dma_handle); 5887 dma_handle);
5888 5888
5889 return rc; 5889 return rc;
5890 } 5890 }
5891 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1); 5891 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5892 5892
5893 5893
5894 /** 5894 /**
5895 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes 5895 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5896 * @ioc: Pointer to a Adapter Strucutre 5896 * @ioc: Pointer to a Adapter Strucutre
5897 * 5897 *
5898 * Return: 5898 * Return:
5899 * 0 on success 5899 * 0 on success
5900 * -EFAULT if read of config page header fails or data pointer not NULL 5900 * -EFAULT if read of config page header fails or data pointer not NULL
5901 * -ENOMEM if pci_alloc failed 5901 * -ENOMEM if pci_alloc failed
5902 **/ 5902 **/
5903 int 5903 int
5904 mpt_findImVolumes(MPT_ADAPTER *ioc) 5904 mpt_findImVolumes(MPT_ADAPTER *ioc)
5905 { 5905 {
5906 IOCPage2_t *pIoc2; 5906 IOCPage2_t *pIoc2;
5907 u8 *mem; 5907 u8 *mem;
5908 dma_addr_t ioc2_dma; 5908 dma_addr_t ioc2_dma;
5909 CONFIGPARMS cfg; 5909 CONFIGPARMS cfg;
5910 ConfigPageHeader_t header; 5910 ConfigPageHeader_t header;
5911 int rc = 0; 5911 int rc = 0;
5912 int iocpage2sz; 5912 int iocpage2sz;
5913 int i; 5913 int i;
5914 5914
5915 if (!ioc->ir_firmware) 5915 if (!ioc->ir_firmware)
5916 return 0; 5916 return 0;
5917 5917
5918 /* Free the old page 5918 /* Free the old page
5919 */ 5919 */
5920 kfree(ioc->raid_data.pIocPg2); 5920 kfree(ioc->raid_data.pIocPg2);
5921 ioc->raid_data.pIocPg2 = NULL; 5921 ioc->raid_data.pIocPg2 = NULL;
5922 mpt_inactive_raid_list_free(ioc); 5922 mpt_inactive_raid_list_free(ioc);
5923 5923
5924 /* Read IOCP2 header then the page. 5924 /* Read IOCP2 header then the page.
5925 */ 5925 */
5926 header.PageVersion = 0; 5926 header.PageVersion = 0;
5927 header.PageLength = 0; 5927 header.PageLength = 0;
5928 header.PageNumber = 2; 5928 header.PageNumber = 2;
5929 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 5929 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5930 cfg.cfghdr.hdr = &header; 5930 cfg.cfghdr.hdr = &header;
5931 cfg.physAddr = -1; 5931 cfg.physAddr = -1;
5932 cfg.pageAddr = 0; 5932 cfg.pageAddr = 0;
5933 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5933 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5934 cfg.dir = 0; 5934 cfg.dir = 0;
5935 cfg.timeout = 0; 5935 cfg.timeout = 0;
5936 if (mpt_config(ioc, &cfg) != 0) 5936 if (mpt_config(ioc, &cfg) != 0)
5937 return -EFAULT; 5937 return -EFAULT;
5938 5938
5939 if (header.PageLength == 0) 5939 if (header.PageLength == 0)
5940 return -EFAULT; 5940 return -EFAULT;
5941 5941
5942 iocpage2sz = header.PageLength * 4; 5942 iocpage2sz = header.PageLength * 4;
5943 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma); 5943 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5944 if (!pIoc2) 5944 if (!pIoc2)
5945 return -ENOMEM; 5945 return -ENOMEM;
5946 5946
5947 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5947 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5948 cfg.physAddr = ioc2_dma; 5948 cfg.physAddr = ioc2_dma;
5949 if (mpt_config(ioc, &cfg) != 0) 5949 if (mpt_config(ioc, &cfg) != 0)
5950 goto out; 5950 goto out;
5951 5951
5952 mem = kmalloc(iocpage2sz, GFP_KERNEL); 5952 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5953 if (!mem) 5953 if (!mem)
5954 goto out; 5954 goto out;
5955 5955
5956 memcpy(mem, (u8 *)pIoc2, iocpage2sz); 5956 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5957 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem; 5957 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5958 5958
5959 mpt_read_ioc_pg_3(ioc); 5959 mpt_read_ioc_pg_3(ioc);
5960 5960
5961 for (i = 0; i < pIoc2->NumActiveVolumes ; i++) 5961 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5962 mpt_inactive_raid_volumes(ioc, 5962 mpt_inactive_raid_volumes(ioc,
5963 pIoc2->RaidVolume[i].VolumeBus, 5963 pIoc2->RaidVolume[i].VolumeBus,
5964 pIoc2->RaidVolume[i].VolumeID); 5964 pIoc2->RaidVolume[i].VolumeID);
5965 5965
5966 out: 5966 out:
5967 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); 5967 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5968 5968
5969 return rc; 5969 return rc;
5970 } 5970 }
5971 5971
5972 static int 5972 static int
5973 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) 5973 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5974 { 5974 {
5975 IOCPage3_t *pIoc3; 5975 IOCPage3_t *pIoc3;
5976 u8 *mem; 5976 u8 *mem;
5977 CONFIGPARMS cfg; 5977 CONFIGPARMS cfg;
5978 ConfigPageHeader_t header; 5978 ConfigPageHeader_t header;
5979 dma_addr_t ioc3_dma; 5979 dma_addr_t ioc3_dma;
5980 int iocpage3sz = 0; 5980 int iocpage3sz = 0;
5981 5981
5982 /* Free the old page 5982 /* Free the old page
5983 */ 5983 */
5984 kfree(ioc->raid_data.pIocPg3); 5984 kfree(ioc->raid_data.pIocPg3);
5985 ioc->raid_data.pIocPg3 = NULL; 5985 ioc->raid_data.pIocPg3 = NULL;
5986 5986
5987 /* There is at least one physical disk. 5987 /* There is at least one physical disk.
5988 * Read and save IOC Page 3 5988 * Read and save IOC Page 3
5989 */ 5989 */
5990 header.PageVersion = 0; 5990 header.PageVersion = 0;
5991 header.PageLength = 0; 5991 header.PageLength = 0;
5992 header.PageNumber = 3; 5992 header.PageNumber = 3;
5993 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 5993 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5994 cfg.cfghdr.hdr = &header; 5994 cfg.cfghdr.hdr = &header;
5995 cfg.physAddr = -1; 5995 cfg.physAddr = -1;
5996 cfg.pageAddr = 0; 5996 cfg.pageAddr = 0;
5997 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5997 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5998 cfg.dir = 0; 5998 cfg.dir = 0;
5999 cfg.timeout = 0; 5999 cfg.timeout = 0;
6000 if (mpt_config(ioc, &cfg) != 0) 6000 if (mpt_config(ioc, &cfg) != 0)
6001 return 0; 6001 return 0;
6002 6002
6003 if (header.PageLength == 0) 6003 if (header.PageLength == 0)
6004 return 0; 6004 return 0;
6005 6005
6006 /* Read Header good, alloc memory 6006 /* Read Header good, alloc memory
6007 */ 6007 */
6008 iocpage3sz = header.PageLength * 4; 6008 iocpage3sz = header.PageLength * 4;
6009 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma); 6009 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6010 if (!pIoc3) 6010 if (!pIoc3)
6011 return 0; 6011 return 0;
6012 6012
6013 /* Read the Page and save the data 6013 /* Read the Page and save the data
6014 * into malloc'd memory. 6014 * into malloc'd memory.
6015 */ 6015 */
6016 cfg.physAddr = ioc3_dma; 6016 cfg.physAddr = ioc3_dma;
6017 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 6017 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6018 if (mpt_config(ioc, &cfg) == 0) { 6018 if (mpt_config(ioc, &cfg) == 0) {
6019 mem = kmalloc(iocpage3sz, GFP_KERNEL); 6019 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6020 if (mem) { 6020 if (mem) {
6021 memcpy(mem, (u8 *)pIoc3, iocpage3sz); 6021 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6022 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem; 6022 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6023 } 6023 }
6024 } 6024 }
6025 6025
6026 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); 6026 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6027 6027
6028 return 0; 6028 return 0;
6029 } 6029 }
6030 6030
6031 static void 6031 static void
6032 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) 6032 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6033 { 6033 {
6034 IOCPage4_t *pIoc4; 6034 IOCPage4_t *pIoc4;
6035 CONFIGPARMS cfg; 6035 CONFIGPARMS cfg;
6036 ConfigPageHeader_t header; 6036 ConfigPageHeader_t header;
6037 dma_addr_t ioc4_dma; 6037 dma_addr_t ioc4_dma;
6038 int iocpage4sz; 6038 int iocpage4sz;
6039 6039
6040 /* Read and save IOC Page 4 6040 /* Read and save IOC Page 4
6041 */ 6041 */
6042 header.PageVersion = 0; 6042 header.PageVersion = 0;
6043 header.PageLength = 0; 6043 header.PageLength = 0;
6044 header.PageNumber = 4; 6044 header.PageNumber = 4;
6045 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 6045 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6046 cfg.cfghdr.hdr = &header; 6046 cfg.cfghdr.hdr = &header;
6047 cfg.physAddr = -1; 6047 cfg.physAddr = -1;
6048 cfg.pageAddr = 0; 6048 cfg.pageAddr = 0;
6049 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 6049 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6050 cfg.dir = 0; 6050 cfg.dir = 0;
6051 cfg.timeout = 0; 6051 cfg.timeout = 0;
6052 if (mpt_config(ioc, &cfg) != 0) 6052 if (mpt_config(ioc, &cfg) != 0)
6053 return; 6053 return;
6054 6054
6055 if (header.PageLength == 0) 6055 if (header.PageLength == 0)
6056 return; 6056 return;
6057 6057
6058 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) { 6058 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6059 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */ 6059 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6060 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); 6060 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6061 if (!pIoc4) 6061 if (!pIoc4)
6062 return; 6062 return;
6063 ioc->alloc_total += iocpage4sz; 6063 ioc->alloc_total += iocpage4sz;
6064 } else { 6064 } else {
6065 ioc4_dma = ioc->spi_data.IocPg4_dma; 6065 ioc4_dma = ioc->spi_data.IocPg4_dma;
6066 iocpage4sz = ioc->spi_data.IocPg4Sz; 6066 iocpage4sz = ioc->spi_data.IocPg4Sz;
6067 } 6067 }
6068 6068
6069 /* Read the Page into dma memory. 6069 /* Read the Page into dma memory.
6070 */ 6070 */
6071 cfg.physAddr = ioc4_dma; 6071 cfg.physAddr = ioc4_dma;
6072 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 6072 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6073 if (mpt_config(ioc, &cfg) == 0) { 6073 if (mpt_config(ioc, &cfg) == 0) {
6074 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4; 6074 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6075 ioc->spi_data.IocPg4_dma = ioc4_dma; 6075 ioc->spi_data.IocPg4_dma = ioc4_dma;
6076 ioc->spi_data.IocPg4Sz = iocpage4sz; 6076 ioc->spi_data.IocPg4Sz = iocpage4sz;
6077 } else { 6077 } else {
6078 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); 6078 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6079 ioc->spi_data.pIocPg4 = NULL; 6079 ioc->spi_data.pIocPg4 = NULL;
6080 ioc->alloc_total -= iocpage4sz; 6080 ioc->alloc_total -= iocpage4sz;
6081 } 6081 }
6082 } 6082 }
6083 6083
6084 static void 6084 static void
6085 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) 6085 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6086 { 6086 {
6087 IOCPage1_t *pIoc1; 6087 IOCPage1_t *pIoc1;
6088 CONFIGPARMS cfg; 6088 CONFIGPARMS cfg;
6089 ConfigPageHeader_t header; 6089 ConfigPageHeader_t header;
6090 dma_addr_t ioc1_dma; 6090 dma_addr_t ioc1_dma;
6091 int iocpage1sz = 0; 6091 int iocpage1sz = 0;
6092 u32 tmp; 6092 u32 tmp;
6093 6093
6094 /* Check the Coalescing Timeout in IOC Page 1 6094 /* Check the Coalescing Timeout in IOC Page 1
6095 */ 6095 */
6096 header.PageVersion = 0; 6096 header.PageVersion = 0;
6097 header.PageLength = 0; 6097 header.PageLength = 0;
6098 header.PageNumber = 1; 6098 header.PageNumber = 1;
6099 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 6099 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6100 cfg.cfghdr.hdr = &header; 6100 cfg.cfghdr.hdr = &header;
6101 cfg.physAddr = -1; 6101 cfg.physAddr = -1;
6102 cfg.pageAddr = 0; 6102 cfg.pageAddr = 0;
6103 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 6103 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6104 cfg.dir = 0; 6104 cfg.dir = 0;
6105 cfg.timeout = 0; 6105 cfg.timeout = 0;
6106 if (mpt_config(ioc, &cfg) != 0) 6106 if (mpt_config(ioc, &cfg) != 0)
6107 return; 6107 return;
6108 6108
6109 if (header.PageLength == 0) 6109 if (header.PageLength == 0)
6110 return; 6110 return;
6111 6111
6112 /* Read Header good, alloc memory 6112 /* Read Header good, alloc memory
6113 */ 6113 */
6114 iocpage1sz = header.PageLength * 4; 6114 iocpage1sz = header.PageLength * 4;
6115 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma); 6115 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6116 if (!pIoc1) 6116 if (!pIoc1)
6117 return; 6117 return;
6118 6118
6119 /* Read the Page and check coalescing timeout 6119 /* Read the Page and check coalescing timeout
6120 */ 6120 */
6121 cfg.physAddr = ioc1_dma; 6121 cfg.physAddr = ioc1_dma;
6122 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 6122 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6123 if (mpt_config(ioc, &cfg) == 0) { 6123 if (mpt_config(ioc, &cfg) == 0) {
6124 6124
6125 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING; 6125 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6126 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) { 6126 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6127 tmp = le32_to_cpu(pIoc1->CoalescingTimeout); 6127 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6128 6128
6129 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n", 6129 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6130 ioc->name, tmp)); 6130 ioc->name, tmp));
6131 6131
6132 if (tmp > MPT_COALESCING_TIMEOUT) { 6132 if (tmp > MPT_COALESCING_TIMEOUT) {
6133 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT); 6133 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6134 6134
6135 /* Write NVRAM and current 6135 /* Write NVRAM and current
6136 */ 6136 */
6137 cfg.dir = 1; 6137 cfg.dir = 1;
6138 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 6138 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6139 if (mpt_config(ioc, &cfg) == 0) { 6139 if (mpt_config(ioc, &cfg) == 0) {
6140 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n", 6140 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6141 ioc->name, MPT_COALESCING_TIMEOUT)); 6141 ioc->name, MPT_COALESCING_TIMEOUT));
6142 6142
6143 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM; 6143 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6144 if (mpt_config(ioc, &cfg) == 0) { 6144 if (mpt_config(ioc, &cfg) == 0) {
6145 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6145 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6146 "Reset NVRAM Coalescing Timeout to = %d\n", 6146 "Reset NVRAM Coalescing Timeout to = %d\n",
6147 ioc->name, MPT_COALESCING_TIMEOUT)); 6147 ioc->name, MPT_COALESCING_TIMEOUT));
6148 } else { 6148 } else {
6149 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6149 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6150 "Reset NVRAM Coalescing Timeout Failed\n", 6150 "Reset NVRAM Coalescing Timeout Failed\n",
6151 ioc->name)); 6151 ioc->name));
6152 } 6152 }
6153 6153
6154 } else { 6154 } else {
6155 dprintk(ioc, printk(MYIOC_s_WARN_FMT 6155 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6156 "Reset of Current Coalescing Timeout Failed!\n", 6156 "Reset of Current Coalescing Timeout Failed!\n",
6157 ioc->name)); 6157 ioc->name));
6158 } 6158 }
6159 } 6159 }
6160 6160
6161 } else { 6161 } else {
6162 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name)); 6162 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6163 } 6163 }
6164 } 6164 }
6165 6165
6166 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); 6166 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6167 6167
6168 return; 6168 return;
6169 } 6169 }
6170 6170
6171 static void 6171 static void
6172 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc) 6172 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6173 { 6173 {
6174 CONFIGPARMS cfg; 6174 CONFIGPARMS cfg;
6175 ConfigPageHeader_t hdr; 6175 ConfigPageHeader_t hdr;
6176 dma_addr_t buf_dma; 6176 dma_addr_t buf_dma;
6177 ManufacturingPage0_t *pbuf = NULL; 6177 ManufacturingPage0_t *pbuf = NULL;
6178 6178
6179 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 6179 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6180 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 6180 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6181 6181
6182 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING; 6182 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6183 cfg.cfghdr.hdr = &hdr; 6183 cfg.cfghdr.hdr = &hdr;
6184 cfg.physAddr = -1; 6184 cfg.physAddr = -1;
6185 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 6185 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6186 cfg.timeout = 10; 6186 cfg.timeout = 10;
6187 6187
6188 if (mpt_config(ioc, &cfg) != 0) 6188 if (mpt_config(ioc, &cfg) != 0)
6189 goto out; 6189 goto out;
6190 6190
6191 if (!cfg.cfghdr.hdr->PageLength) 6191 if (!cfg.cfghdr.hdr->PageLength)
6192 goto out; 6192 goto out;
6193 6193
6194 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 6194 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6195 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma); 6195 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6196 if (!pbuf) 6196 if (!pbuf)
6197 goto out; 6197 goto out;
6198 6198
6199 cfg.physAddr = buf_dma; 6199 cfg.physAddr = buf_dma;
6200 6200
6201 if (mpt_config(ioc, &cfg) != 0) 6201 if (mpt_config(ioc, &cfg) != 0)
6202 goto out; 6202 goto out;
6203 6203
6204 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name)); 6204 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6205 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly)); 6205 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6206 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer)); 6206 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6207 6207
6208 out: 6208 out:
6209 6209
6210 if (pbuf) 6210 if (pbuf)
6211 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); 6211 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6212 } 6212 }
6213 6213
6214 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6214 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6215 /** 6215 /**
6216 * SendEventNotification - Send EventNotification (on or off) request to adapter 6216 * SendEventNotification - Send EventNotification (on or off) request to adapter
6217 * @ioc: Pointer to MPT_ADAPTER structure 6217 * @ioc: Pointer to MPT_ADAPTER structure
6218 * @EvSwitch: Event switch flags 6218 * @EvSwitch: Event switch flags
6219 * @sleepFlag: Specifies whether the process can sleep 6219 * @sleepFlag: Specifies whether the process can sleep
6220 */ 6220 */
6221 static int 6221 static int
6222 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag) 6222 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6223 { 6223 {
6224 EventNotification_t evn; 6224 EventNotification_t evn;
6225 MPIDefaultReply_t reply_buf; 6225 MPIDefaultReply_t reply_buf;
6226 6226
6227 memset(&evn, 0, sizeof(EventNotification_t)); 6227 memset(&evn, 0, sizeof(EventNotification_t));
6228 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t)); 6228 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6229 6229
6230 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION; 6230 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6231 evn.Switch = EvSwitch; 6231 evn.Switch = EvSwitch;
6232 evn.MsgContext = cpu_to_le32(mpt_base_index << 16); 6232 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6233 6233
6234 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6234 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6235 "Sending EventNotification (%d) request %p\n", 6235 "Sending EventNotification (%d) request %p\n",
6236 ioc->name, EvSwitch, &evn)); 6236 ioc->name, EvSwitch, &evn));
6237 6237
6238 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t), 6238 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6239 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30, 6239 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6240 sleepFlag); 6240 sleepFlag);
6241 } 6241 }
6242 6242
6243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6244 /** 6244 /**
6245 * SendEventAck - Send EventAck request to MPT adapter. 6245 * SendEventAck - Send EventAck request to MPT adapter.
6246 * @ioc: Pointer to MPT_ADAPTER structure 6246 * @ioc: Pointer to MPT_ADAPTER structure
6247 * @evnp: Pointer to original EventNotification request 6247 * @evnp: Pointer to original EventNotification request
6248 */ 6248 */
6249 static int 6249 static int
6250 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) 6250 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6251 { 6251 {
6252 EventAck_t *pAck; 6252 EventAck_t *pAck;
6253 6253
6254 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 6254 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6255 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", 6255 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6256 ioc->name, __func__)); 6256 ioc->name, __func__));
6257 return -1; 6257 return -1;
6258 } 6258 }
6259 6259
6260 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name)); 6260 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6261 6261
6262 pAck->Function = MPI_FUNCTION_EVENT_ACK; 6262 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6263 pAck->ChainOffset = 0; 6263 pAck->ChainOffset = 0;
6264 pAck->Reserved[0] = pAck->Reserved[1] = 0; 6264 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6265 pAck->MsgFlags = 0; 6265 pAck->MsgFlags = 0;
6266 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0; 6266 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6267 pAck->Event = evnp->Event; 6267 pAck->Event = evnp->Event;
6268 pAck->EventContext = evnp->EventContext; 6268 pAck->EventContext = evnp->EventContext;
6269 6269
6270 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck); 6270 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6271 6271
6272 return 0; 6272 return 0;
6273 } 6273 }
6274 6274
6275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6276 /** 6276 /**
6277 * mpt_config - Generic function to issue config message 6277 * mpt_config - Generic function to issue config message
6278 * @ioc: Pointer to an adapter structure 6278 * @ioc: Pointer to an adapter structure
6279 * @pCfg: Pointer to a configuration structure. Struct contains 6279 * @pCfg: Pointer to a configuration structure. Struct contains
6280 * action, page address, direction, physical address 6280 * action, page address, direction, physical address
6281 * and pointer to a configuration page header 6281 * and pointer to a configuration page header
6282 * Page header is updated. 6282 * Page header is updated.
6283 * 6283 *
6284 * Returns 0 for success 6284 * Returns 0 for success
6285 * -EPERM if not allowed due to ISR context 6285 * -EPERM if not allowed due to ISR context
6286 * -EAGAIN if no msg frames currently available 6286 * -EAGAIN if no msg frames currently available
6287 * -EFAULT for non-successful reply or no reply (timeout) 6287 * -EFAULT for non-successful reply or no reply (timeout)
6288 */ 6288 */
6289 int 6289 int
6290 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) 6290 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6291 { 6291 {
6292 Config_t *pReq; 6292 Config_t *pReq;
6293 ConfigReply_t *pReply; 6293 ConfigReply_t *pReply;
6294 ConfigExtendedPageHeader_t *pExtHdr = NULL; 6294 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6295 MPT_FRAME_HDR *mf; 6295 MPT_FRAME_HDR *mf;
6296 int ii; 6296 int ii;
6297 int flagsLength; 6297 int flagsLength;
6298 long timeout; 6298 long timeout;
6299 int ret; 6299 int ret;
6300 u8 page_type = 0, extend_page; 6300 u8 page_type = 0, extend_page;
6301 unsigned long timeleft; 6301 unsigned long timeleft;
6302 unsigned long flags; 6302 unsigned long flags;
6303 int in_isr; 6303 int in_isr;
6304 u8 issue_hard_reset = 0; 6304 u8 issue_hard_reset = 0;
6305 u8 retry_count = 0; 6305 u8 retry_count = 0;
6306 6306
6307 /* Prevent calling wait_event() (below), if caller happens 6307 /* Prevent calling wait_event() (below), if caller happens
6308 * to be in ISR context, because that is fatal! 6308 * to be in ISR context, because that is fatal!
6309 */ 6309 */
6310 in_isr = in_interrupt(); 6310 in_isr = in_interrupt();
6311 if (in_isr) { 6311 if (in_isr) {
6312 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n", 6312 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6313 ioc->name)); 6313 ioc->name));
6314 return -EPERM; 6314 return -EPERM;
6315 } 6315 }
6316 6316
6317 /* don't send a config page during diag reset */ 6317 /* don't send a config page during diag reset */
6318 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6318 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6319 if (ioc->ioc_reset_in_progress) { 6319 if (ioc->ioc_reset_in_progress) {
6320 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6320 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6321 "%s: busy with host reset\n", ioc->name, __func__)); 6321 "%s: busy with host reset\n", ioc->name, __func__));
6322 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6322 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6323 return -EBUSY; 6323 return -EBUSY;
6324 } 6324 }
6325 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6325 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6326 6326
6327 /* don't send if no chance of success */ 6327 /* don't send if no chance of success */
6328 if (!ioc->active || 6328 if (!ioc->active ||
6329 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) { 6329 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6330 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6330 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6331 "%s: ioc not operational, %d, %xh\n", 6331 "%s: ioc not operational, %d, %xh\n",
6332 ioc->name, __func__, ioc->active, 6332 ioc->name, __func__, ioc->active,
6333 mpt_GetIocState(ioc, 0))); 6333 mpt_GetIocState(ioc, 0)));
6334 return -EFAULT; 6334 return -EFAULT;
6335 } 6335 }
6336 6336
6337 retry_config: 6337 retry_config:
6338 mutex_lock(&ioc->mptbase_cmds.mutex); 6338 mutex_lock(&ioc->mptbase_cmds.mutex);
6339 /* init the internal cmd struct */ 6339 /* init the internal cmd struct */
6340 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE); 6340 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6341 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status) 6341 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6342 6342
6343 /* Get and Populate a free Frame 6343 /* Get and Populate a free Frame
6344 */ 6344 */
6345 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 6345 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6346 dcprintk(ioc, printk(MYIOC_s_WARN_FMT 6346 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6347 "mpt_config: no msg frames!\n", ioc->name)); 6347 "mpt_config: no msg frames!\n", ioc->name));
6348 ret = -EAGAIN; 6348 ret = -EAGAIN;
6349 goto out; 6349 goto out;
6350 } 6350 }
6351 6351
6352 pReq = (Config_t *)mf; 6352 pReq = (Config_t *)mf;
6353 pReq->Action = pCfg->action; 6353 pReq->Action = pCfg->action;
6354 pReq->Reserved = 0; 6354 pReq->Reserved = 0;
6355 pReq->ChainOffset = 0; 6355 pReq->ChainOffset = 0;
6356 pReq->Function = MPI_FUNCTION_CONFIG; 6356 pReq->Function = MPI_FUNCTION_CONFIG;
6357 6357
6358 /* Assume page type is not extended and clear "reserved" fields. */ 6358 /* Assume page type is not extended and clear "reserved" fields. */
6359 pReq->ExtPageLength = 0; 6359 pReq->ExtPageLength = 0;
6360 pReq->ExtPageType = 0; 6360 pReq->ExtPageType = 0;
6361 pReq->MsgFlags = 0; 6361 pReq->MsgFlags = 0;
6362 6362
6363 for (ii=0; ii < 8; ii++) 6363 for (ii=0; ii < 8; ii++)
6364 pReq->Reserved2[ii] = 0; 6364 pReq->Reserved2[ii] = 0;
6365 6365
6366 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion; 6366 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6367 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength; 6367 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6368 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber; 6368 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6369 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); 6369 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6370 6370
6371 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { 6371 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6372 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr; 6372 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6373 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength); 6373 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6374 pReq->ExtPageType = pExtHdr->ExtPageType; 6374 pReq->ExtPageType = pExtHdr->ExtPageType;
6375 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 6375 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6376 6376
6377 /* Page Length must be treated as a reserved field for the 6377 /* Page Length must be treated as a reserved field for the
6378 * extended header. 6378 * extended header.
6379 */ 6379 */
6380 pReq->Header.PageLength = 0; 6380 pReq->Header.PageLength = 0;
6381 } 6381 }
6382 6382
6383 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr); 6383 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6384 6384
6385 /* Add a SGE to the config request. 6385 /* Add a SGE to the config request.
6386 */ 6386 */
6387 if (pCfg->dir) 6387 if (pCfg->dir)
6388 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE; 6388 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6389 else 6389 else
6390 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; 6390 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6391 6391
6392 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == 6392 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6393 MPI_CONFIG_PAGETYPE_EXTENDED) { 6393 MPI_CONFIG_PAGETYPE_EXTENDED) {
6394 flagsLength |= pExtHdr->ExtPageLength * 4; 6394 flagsLength |= pExtHdr->ExtPageLength * 4;
6395 page_type = pReq->ExtPageType; 6395 page_type = pReq->ExtPageType;
6396 extend_page = 1; 6396 extend_page = 1;
6397 } else { 6397 } else {
6398 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4; 6398 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6399 page_type = pReq->Header.PageType; 6399 page_type = pReq->Header.PageType;
6400 extend_page = 0; 6400 extend_page = 0;
6401 } 6401 }
6402 6402
6403 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6403 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6404 "Sending Config request type 0x%x, page 0x%x and action %d\n", 6404 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6405 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action)); 6405 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6406 6406
6407 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); 6407 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6408 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout; 6408 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6409 mpt_put_msg_frame(mpt_base_index, ioc, mf); 6409 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6410 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 6410 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6411 timeout); 6411 timeout);
6412 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { 6412 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6413 ret = -ETIME; 6413 ret = -ETIME;
6414 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6414 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6415 "Failed Sending Config request type 0x%x, page 0x%x," 6415 "Failed Sending Config request type 0x%x, page 0x%x,"
6416 " action %d, status %xh, time left %ld\n\n", 6416 " action %d, status %xh, time left %ld\n\n",
6417 ioc->name, page_type, pReq->Header.PageNumber, 6417 ioc->name, page_type, pReq->Header.PageNumber,
6418 pReq->Action, ioc->mptbase_cmds.status, timeleft)); 6418 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6419 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) 6419 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6420 goto out; 6420 goto out;
6421 if (!timeleft) 6421 if (!timeleft)
6422 issue_hard_reset = 1; 6422 issue_hard_reset = 1;
6423 goto out; 6423 goto out;
6424 } 6424 }
6425 6425
6426 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { 6426 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6427 ret = -1; 6427 ret = -1;
6428 goto out; 6428 goto out;
6429 } 6429 }
6430 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply; 6430 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6431 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK; 6431 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6432 if (ret == MPI_IOCSTATUS_SUCCESS) { 6432 if (ret == MPI_IOCSTATUS_SUCCESS) {
6433 if (extend_page) { 6433 if (extend_page) {
6434 pCfg->cfghdr.ehdr->ExtPageLength = 6434 pCfg->cfghdr.ehdr->ExtPageLength =
6435 le16_to_cpu(pReply->ExtPageLength); 6435 le16_to_cpu(pReply->ExtPageLength);
6436 pCfg->cfghdr.ehdr->ExtPageType = 6436 pCfg->cfghdr.ehdr->ExtPageType =
6437 pReply->ExtPageType; 6437 pReply->ExtPageType;
6438 } 6438 }
6439 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion; 6439 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6440 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength; 6440 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6441 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber; 6441 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6442 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType; 6442 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6443 6443
6444 } 6444 }
6445 6445
6446 if (retry_count) 6446 if (retry_count)
6447 printk(MYIOC_s_INFO_FMT "Retry completed " 6447 printk(MYIOC_s_INFO_FMT "Retry completed "
6448 "ret=0x%x timeleft=%ld\n", 6448 "ret=0x%x timeleft=%ld\n",
6449 ioc->name, ret, timeleft); 6449 ioc->name, ret, timeleft);
6450 6450
6451 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n", 6451 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6452 ret, le32_to_cpu(pReply->IOCLogInfo))); 6452 ret, le32_to_cpu(pReply->IOCLogInfo)));
6453 6453
6454 out: 6454 out:
6455 6455
6456 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status) 6456 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6457 mutex_unlock(&ioc->mptbase_cmds.mutex); 6457 mutex_unlock(&ioc->mptbase_cmds.mutex);
6458 if (issue_hard_reset) { 6458 if (issue_hard_reset) {
6459 issue_hard_reset = 0; 6459 issue_hard_reset = 0;
6460 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", 6460 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6461 ioc->name, __func__); 6461 ioc->name, __func__);
6462 if (retry_count == 0) { 6462 if (retry_count == 0) {
6463 if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0) 6463 if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6464 retry_count++; 6464 retry_count++;
6465 } else 6465 } else
6466 mpt_HardResetHandler(ioc, CAN_SLEEP); 6466 mpt_HardResetHandler(ioc, CAN_SLEEP);
6467 6467
6468 mpt_free_msg_frame(ioc, mf); 6468 mpt_free_msg_frame(ioc, mf);
6469 /* attempt one retry for a timed out command */ 6469 /* attempt one retry for a timed out command */
6470 if (retry_count < 2) { 6470 if (retry_count < 2) {
6471 printk(MYIOC_s_INFO_FMT 6471 printk(MYIOC_s_INFO_FMT
6472 "Attempting Retry Config request" 6472 "Attempting Retry Config request"
6473 " type 0x%x, page 0x%x," 6473 " type 0x%x, page 0x%x,"
6474 " action %d\n", ioc->name, page_type, 6474 " action %d\n", ioc->name, page_type,
6475 pCfg->cfghdr.hdr->PageNumber, pCfg->action); 6475 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6476 retry_count++; 6476 retry_count++;
6477 goto retry_config; 6477 goto retry_config;
6478 } 6478 }
6479 } 6479 }
6480 return ret; 6480 return ret;
6481 6481
6482 } 6482 }
6483 6483
6484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6485 /** 6485 /**
6486 * mpt_ioc_reset - Base cleanup for hard reset 6486 * mpt_ioc_reset - Base cleanup for hard reset
6487 * @ioc: Pointer to the adapter structure 6487 * @ioc: Pointer to the adapter structure
6488 * @reset_phase: Indicates pre- or post-reset functionality 6488 * @reset_phase: Indicates pre- or post-reset functionality
6489 * 6489 *
6490 * Remark: Frees resources with internally generated commands. 6490 * Remark: Frees resources with internally generated commands.
6491 */ 6491 */
6492 static int 6492 static int
6493 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) 6493 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6494 { 6494 {
6495 switch (reset_phase) { 6495 switch (reset_phase) {
6496 case MPT_IOC_SETUP_RESET: 6496 case MPT_IOC_SETUP_RESET:
6497 ioc->taskmgmt_quiesce_io = 1; 6497 ioc->taskmgmt_quiesce_io = 1;
6498 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6498 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6499 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__)); 6499 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6500 break; 6500 break;
6501 case MPT_IOC_PRE_RESET: 6501 case MPT_IOC_PRE_RESET:
6502 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6502 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6503 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__)); 6503 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6504 break; 6504 break;
6505 case MPT_IOC_POST_RESET: 6505 case MPT_IOC_POST_RESET:
6506 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6506 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6507 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__)); 6507 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6508 /* wake up mptbase_cmds */ 6508 /* wake up mptbase_cmds */
6509 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) { 6509 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6510 ioc->mptbase_cmds.status |= 6510 ioc->mptbase_cmds.status |=
6511 MPT_MGMT_STATUS_DID_IOCRESET; 6511 MPT_MGMT_STATUS_DID_IOCRESET;
6512 complete(&ioc->mptbase_cmds.done); 6512 complete(&ioc->mptbase_cmds.done);
6513 } 6513 }
6514 /* wake up taskmgmt_cmds */ 6514 /* wake up taskmgmt_cmds */
6515 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) { 6515 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6516 ioc->taskmgmt_cmds.status |= 6516 ioc->taskmgmt_cmds.status |=
6517 MPT_MGMT_STATUS_DID_IOCRESET; 6517 MPT_MGMT_STATUS_DID_IOCRESET;
6518 complete(&ioc->taskmgmt_cmds.done); 6518 complete(&ioc->taskmgmt_cmds.done);
6519 } 6519 }
6520 break; 6520 break;
6521 default: 6521 default:
6522 break; 6522 break;
6523 } 6523 }
6524 6524
6525 return 1; /* currently means nothing really */ 6525 return 1; /* currently means nothing really */
6526 } 6526 }
6527 6527
6528 6528
6529 #ifdef CONFIG_PROC_FS /* { */ 6529 #ifdef CONFIG_PROC_FS /* { */
6530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6531 /* 6531 /*
6532 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff... 6532 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6533 */ 6533 */
6534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6535 /** 6535 /**
6536 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries. 6536 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6537 * 6537 *
6538 * Returns 0 for success, non-zero for failure. 6538 * Returns 0 for success, non-zero for failure.
6539 */ 6539 */
6540 static int 6540 static int
6541 procmpt_create(void) 6541 procmpt_create(void)
6542 { 6542 {
6543 struct proc_dir_entry *ent; 6543 struct proc_dir_entry *ent;
6544 6544
6545 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL); 6545 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6546 if (mpt_proc_root_dir == NULL) 6546 if (mpt_proc_root_dir == NULL)
6547 return -ENOTDIR; 6547 return -ENOTDIR;
6548 6548
6549 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir); 6549 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6550 if (ent) 6550 if (ent)
6551 ent->read_proc = procmpt_summary_read; 6551 ent->read_proc = procmpt_summary_read;
6552 6552
6553 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir); 6553 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6554 if (ent) 6554 if (ent)
6555 ent->read_proc = procmpt_version_read; 6555 ent->read_proc = procmpt_version_read;
6556 6556
6557 return 0; 6557 return 0;
6558 } 6558 }
6559 6559
6560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6561 /** 6561 /**
6562 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries. 6562 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6563 * 6563 *
6564 * Returns 0 for success, non-zero for failure. 6564 * Returns 0 for success, non-zero for failure.
6565 */ 6565 */
6566 static void 6566 static void
6567 procmpt_destroy(void) 6567 procmpt_destroy(void)
6568 { 6568 {
6569 remove_proc_entry("version", mpt_proc_root_dir); 6569 remove_proc_entry("version", mpt_proc_root_dir);
6570 remove_proc_entry("summary", mpt_proc_root_dir); 6570 remove_proc_entry("summary", mpt_proc_root_dir);
6571 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL); 6571 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6572 } 6572 }
6573 6573
6574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6575 /** 6575 /**
6576 * procmpt_summary_read - Handle read request of a summary file 6576 * procmpt_summary_read - Handle read request of a summary file
6577 * @buf: Pointer to area to write information 6577 * @buf: Pointer to area to write information
6578 * @start: Pointer to start pointer 6578 * @start: Pointer to start pointer
6579 * @offset: Offset to start writing 6579 * @offset: Offset to start writing
6580 * @request: Amount of read data requested 6580 * @request: Amount of read data requested
6581 * @eof: Pointer to EOF integer 6581 * @eof: Pointer to EOF integer
6582 * @data: Pointer 6582 * @data: Pointer
6583 * 6583 *
6584 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary. 6584 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6585 * Returns number of characters written to process performing the read. 6585 * Returns number of characters written to process performing the read.
6586 */ 6586 */
6587 static int 6587 static int
6588 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6588 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6589 { 6589 {
6590 MPT_ADAPTER *ioc; 6590 MPT_ADAPTER *ioc;
6591 char *out = buf; 6591 char *out = buf;
6592 int len; 6592 int len;
6593 6593
6594 if (data) { 6594 if (data) {
6595 int more = 0; 6595 int more = 0;
6596 6596
6597 ioc = data; 6597 ioc = data;
6598 mpt_print_ioc_summary(ioc, out, &more, 0, 1); 6598 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6599 6599
6600 out += more; 6600 out += more;
6601 } else { 6601 } else {
6602 list_for_each_entry(ioc, &ioc_list, list) { 6602 list_for_each_entry(ioc, &ioc_list, list) {
6603 int more = 0; 6603 int more = 0;
6604 6604
6605 mpt_print_ioc_summary(ioc, out, &more, 0, 1); 6605 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6606 6606
6607 out += more; 6607 out += more;
6608 if ((out-buf) >= request) 6608 if ((out-buf) >= request)
6609 break; 6609 break;
6610 } 6610 }
6611 } 6611 }
6612 6612
6613 len = out - buf; 6613 len = out - buf;
6614 6614
6615 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6615 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6616 } 6616 }
6617 6617
6618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6619 /** 6619 /**
6620 * procmpt_version_read - Handle read request from /proc/mpt/version. 6620 * procmpt_version_read - Handle read request from /proc/mpt/version.
6621 * @buf: Pointer to area to write information 6621 * @buf: Pointer to area to write information
6622 * @start: Pointer to start pointer 6622 * @start: Pointer to start pointer
6623 * @offset: Offset to start writing 6623 * @offset: Offset to start writing
6624 * @request: Amount of read data requested 6624 * @request: Amount of read data requested
6625 * @eof: Pointer to EOF integer 6625 * @eof: Pointer to EOF integer
6626 * @data: Pointer 6626 * @data: Pointer
6627 * 6627 *
6628 * Returns number of characters written to process performing the read. 6628 * Returns number of characters written to process performing the read.
6629 */ 6629 */
6630 static int 6630 static int
6631 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6631 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6632 { 6632 {
6633 u8 cb_idx; 6633 u8 cb_idx;
6634 int scsi, fc, sas, lan, ctl, targ, dmp; 6634 int scsi, fc, sas, lan, ctl, targ, dmp;
6635 char *drvname; 6635 char *drvname;
6636 int len; 6636 int len;
6637 6637
6638 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON); 6638 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6639 len += sprintf(buf+len, " Fusion MPT base driver\n"); 6639 len += sprintf(buf+len, " Fusion MPT base driver\n");
6640 6640
6641 scsi = fc = sas = lan = ctl = targ = dmp = 0; 6641 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6642 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6642 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6643 drvname = NULL; 6643 drvname = NULL;
6644 if (MptCallbacks[cb_idx]) { 6644 if (MptCallbacks[cb_idx]) {
6645 switch (MptDriverClass[cb_idx]) { 6645 switch (MptDriverClass[cb_idx]) {
6646 case MPTSPI_DRIVER: 6646 case MPTSPI_DRIVER:
6647 if (!scsi++) drvname = "SPI host"; 6647 if (!scsi++) drvname = "SPI host";
6648 break; 6648 break;
6649 case MPTFC_DRIVER: 6649 case MPTFC_DRIVER:
6650 if (!fc++) drvname = "FC host"; 6650 if (!fc++) drvname = "FC host";
6651 break; 6651 break;
6652 case MPTSAS_DRIVER: 6652 case MPTSAS_DRIVER:
6653 if (!sas++) drvname = "SAS host"; 6653 if (!sas++) drvname = "SAS host";
6654 break; 6654 break;
6655 case MPTLAN_DRIVER: 6655 case MPTLAN_DRIVER:
6656 if (!lan++) drvname = "LAN"; 6656 if (!lan++) drvname = "LAN";
6657 break; 6657 break;
6658 case MPTSTM_DRIVER: 6658 case MPTSTM_DRIVER:
6659 if (!targ++) drvname = "SCSI target"; 6659 if (!targ++) drvname = "SCSI target";
6660 break; 6660 break;
6661 case MPTCTL_DRIVER: 6661 case MPTCTL_DRIVER:
6662 if (!ctl++) drvname = "ioctl"; 6662 if (!ctl++) drvname = "ioctl";
6663 break; 6663 break;
6664 } 6664 }
6665 6665
6666 if (drvname) 6666 if (drvname)
6667 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname); 6667 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6668 } 6668 }
6669 } 6669 }
6670 6670
6671 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6671 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6672 } 6672 }
6673 6673
6674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6675 /** 6675 /**
6676 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info. 6676 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6677 * @buf: Pointer to area to write information 6677 * @buf: Pointer to area to write information
6678 * @start: Pointer to start pointer 6678 * @start: Pointer to start pointer
6679 * @offset: Offset to start writing 6679 * @offset: Offset to start writing
6680 * @request: Amount of read data requested 6680 * @request: Amount of read data requested
6681 * @eof: Pointer to EOF integer 6681 * @eof: Pointer to EOF integer
6682 * @data: Pointer 6682 * @data: Pointer
6683 * 6683 *
6684 * Returns number of characters written to process performing the read. 6684 * Returns number of characters written to process performing the read.
6685 */ 6685 */
6686 static int 6686 static int
6687 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6687 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6688 { 6688 {
6689 MPT_ADAPTER *ioc = data; 6689 MPT_ADAPTER *ioc = data;
6690 int len; 6690 int len;
6691 char expVer[32]; 6691 char expVer[32];
6692 int sz; 6692 int sz;
6693 int p; 6693 int p;
6694 6694
6695 mpt_get_fw_exp_ver(expVer, ioc); 6695 mpt_get_fw_exp_ver(expVer, ioc);
6696 6696
6697 len = sprintf(buf, "%s:", ioc->name); 6697 len = sprintf(buf, "%s:", ioc->name);
6698 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) 6698 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6699 len += sprintf(buf+len, " (f/w download boot flag set)"); 6699 len += sprintf(buf+len, " (f/w download boot flag set)");
6700 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL) 6700 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6701 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!"); 6701 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6702 6702
6703 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n", 6703 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6704 ioc->facts.ProductID, 6704 ioc->facts.ProductID,
6705 ioc->prod_name); 6705 ioc->prod_name);
6706 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer); 6706 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6707 if (ioc->facts.FWImageSize) 6707 if (ioc->facts.FWImageSize)
6708 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize); 6708 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6709 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion); 6709 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6710 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit); 6710 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6711 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState); 6711 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6712 6712
6713 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n", 6713 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6714 ioc->facts.CurrentHostMfaHighAddr); 6714 ioc->facts.CurrentHostMfaHighAddr);
6715 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n", 6715 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6716 ioc->facts.CurrentSenseBufferHighAddr); 6716 ioc->facts.CurrentSenseBufferHighAddr);
6717 6717
6718 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth); 6718 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6719 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize); 6719 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6720 6720
6721 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n", 6721 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6722 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma); 6722 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6723 /* 6723 /*
6724 * Rounding UP to nearest 4-kB boundary here... 6724 * Rounding UP to nearest 4-kB boundary here...
6725 */ 6725 */
6726 sz = (ioc->req_sz * ioc->req_depth) + 128; 6726 sz = (ioc->req_sz * ioc->req_depth) + 128;
6727 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000; 6727 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6728 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n", 6728 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6729 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz); 6729 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6730 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n", 6730 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6731 4*ioc->facts.RequestFrameSize, 6731 4*ioc->facts.RequestFrameSize,
6732 ioc->facts.GlobalCredits); 6732 ioc->facts.GlobalCredits);
6733 6733
6734 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n", 6734 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6735 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma); 6735 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6736 sz = (ioc->reply_sz * ioc->reply_depth) + 128; 6736 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6737 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n", 6737 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6738 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz); 6738 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6739 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n", 6739 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6740 ioc->facts.CurReplyFrameSize, 6740 ioc->facts.CurReplyFrameSize,
6741 ioc->facts.ReplyQueueDepth); 6741 ioc->facts.ReplyQueueDepth);
6742 6742
6743 len += sprintf(buf+len, " MaxDevices = %d\n", 6743 len += sprintf(buf+len, " MaxDevices = %d\n",
6744 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices); 6744 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6745 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses); 6745 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6746 6746
6747 /* per-port info */ 6747 /* per-port info */
6748 for (p=0; p < ioc->facts.NumberOfPorts; p++) { 6748 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6749 len += sprintf(buf+len, " PortNumber = %d (of %d)\n", 6749 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6750 p+1, 6750 p+1,
6751 ioc->facts.NumberOfPorts); 6751 ioc->facts.NumberOfPorts);
6752 if (ioc->bus_type == FC) { 6752 if (ioc->bus_type == FC) {
6753 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { 6753 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6754 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 6754 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6755 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", 6755 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6756 a[5], a[4], a[3], a[2], a[1], a[0]); 6756 a[5], a[4], a[3], a[2], a[1], a[0]);
6757 } 6757 }
6758 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n", 6758 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6759 ioc->fc_port_page0[p].WWNN.High, 6759 ioc->fc_port_page0[p].WWNN.High,
6760 ioc->fc_port_page0[p].WWNN.Low, 6760 ioc->fc_port_page0[p].WWNN.Low,
6761 ioc->fc_port_page0[p].WWPN.High, 6761 ioc->fc_port_page0[p].WWPN.High,
6762 ioc->fc_port_page0[p].WWPN.Low); 6762 ioc->fc_port_page0[p].WWPN.Low);
6763 } 6763 }
6764 } 6764 }
6765 6765
6766 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6766 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6767 } 6767 }
6768 6768
6769 #endif /* CONFIG_PROC_FS } */ 6769 #endif /* CONFIG_PROC_FS } */
6770 6770
6771 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6771 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6772 static void 6772 static void
6773 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc) 6773 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6774 { 6774 {
6775 buf[0] ='\0'; 6775 buf[0] ='\0';
6776 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) { 6776 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6777 sprintf(buf, " (Exp %02d%02d)", 6777 sprintf(buf, " (Exp %02d%02d)",
6778 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */ 6778 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6779 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */ 6779 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6780 6780
6781 /* insider hack! */ 6781 /* insider hack! */
6782 if ((ioc->facts.FWVersion.Word >> 8) & 0x80) 6782 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6783 strcat(buf, " [MDBG]"); 6783 strcat(buf, " [MDBG]");
6784 } 6784 }
6785 } 6785 }
6786 6786
6787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6788 /** 6788 /**
6789 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer. 6789 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6790 * @ioc: Pointer to MPT_ADAPTER structure 6790 * @ioc: Pointer to MPT_ADAPTER structure
6791 * @buffer: Pointer to buffer where IOC summary info should be written 6791 * @buffer: Pointer to buffer where IOC summary info should be written
6792 * @size: Pointer to number of bytes we wrote (set by this routine) 6792 * @size: Pointer to number of bytes we wrote (set by this routine)
6793 * @len: Offset at which to start writing in buffer 6793 * @len: Offset at which to start writing in buffer
6794 * @showlan: Display LAN stuff? 6794 * @showlan: Display LAN stuff?
6795 * 6795 *
6796 * This routine writes (english readable) ASCII text, which represents 6796 * This routine writes (english readable) ASCII text, which represents
6797 * a summary of IOC information, to a buffer. 6797 * a summary of IOC information, to a buffer.
6798 */ 6798 */
6799 void 6799 void
6800 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan) 6800 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6801 { 6801 {
6802 char expVer[32]; 6802 char expVer[32];
6803 int y; 6803 int y;
6804 6804
6805 mpt_get_fw_exp_ver(expVer, ioc); 6805 mpt_get_fw_exp_ver(expVer, ioc);
6806 6806
6807 /* 6807 /*
6808 * Shorter summary of attached ioc's... 6808 * Shorter summary of attached ioc's...
6809 */ 6809 */
6810 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d", 6810 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6811 ioc->name, 6811 ioc->name,
6812 ioc->prod_name, 6812 ioc->prod_name,
6813 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */ 6813 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6814 ioc->facts.FWVersion.Word, 6814 ioc->facts.FWVersion.Word,
6815 expVer, 6815 expVer,
6816 ioc->facts.NumberOfPorts, 6816 ioc->facts.NumberOfPorts,
6817 ioc->req_depth); 6817 ioc->req_depth);
6818 6818
6819 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) { 6819 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6820 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 6820 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6821 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X", 6821 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6822 a[5], a[4], a[3], a[2], a[1], a[0]); 6822 a[5], a[4], a[3], a[2], a[1], a[0]);
6823 } 6823 }
6824 6824
6825 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq); 6825 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6826 6826
6827 if (!ioc->active) 6827 if (!ioc->active)
6828 y += sprintf(buffer+len+y, " (disabled)"); 6828 y += sprintf(buffer+len+y, " (disabled)");
6829 6829
6830 y += sprintf(buffer+len+y, "\n"); 6830 y += sprintf(buffer+len+y, "\n");
6831 6831
6832 *size = y; 6832 *size = y;
6833 } 6833 }
6834 /** 6834 /**
6835 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management 6835 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6836 * @ioc: Pointer to MPT_ADAPTER structure 6836 * @ioc: Pointer to MPT_ADAPTER structure
6837 * 6837 *
6838 * Returns 0 for SUCCESS or -1 if FAILED. 6838 * Returns 0 for SUCCESS or -1 if FAILED.
6839 * 6839 *
6840 * If -1 is return, then it was not possible to set the flags 6840 * If -1 is return, then it was not possible to set the flags
6841 **/ 6841 **/
6842 int 6842 int
6843 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc) 6843 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6844 { 6844 {
6845 unsigned long flags; 6845 unsigned long flags;
6846 int retval; 6846 int retval;
6847 6847
6848 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6848 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6849 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress || 6849 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6850 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) { 6850 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6851 retval = -1; 6851 retval = -1;
6852 goto out; 6852 goto out;
6853 } 6853 }
6854 retval = 0; 6854 retval = 0;
6855 ioc->taskmgmt_in_progress = 1; 6855 ioc->taskmgmt_in_progress = 1;
6856 ioc->taskmgmt_quiesce_io = 1; 6856 ioc->taskmgmt_quiesce_io = 1;
6857 if (ioc->alt_ioc) { 6857 if (ioc->alt_ioc) {
6858 ioc->alt_ioc->taskmgmt_in_progress = 1; 6858 ioc->alt_ioc->taskmgmt_in_progress = 1;
6859 ioc->alt_ioc->taskmgmt_quiesce_io = 1; 6859 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6860 } 6860 }
6861 out: 6861 out:
6862 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6862 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6863 return retval; 6863 return retval;
6864 } 6864 }
6865 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag); 6865 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6866 6866
6867 /** 6867 /**
6868 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management 6868 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6869 * @ioc: Pointer to MPT_ADAPTER structure 6869 * @ioc: Pointer to MPT_ADAPTER structure
6870 * 6870 *
6871 **/ 6871 **/
6872 void 6872 void
6873 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc) 6873 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6874 { 6874 {
6875 unsigned long flags; 6875 unsigned long flags;
6876 6876
6877 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6877 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6878 ioc->taskmgmt_in_progress = 0; 6878 ioc->taskmgmt_in_progress = 0;
6879 ioc->taskmgmt_quiesce_io = 0; 6879 ioc->taskmgmt_quiesce_io = 0;
6880 if (ioc->alt_ioc) { 6880 if (ioc->alt_ioc) {
6881 ioc->alt_ioc->taskmgmt_in_progress = 0; 6881 ioc->alt_ioc->taskmgmt_in_progress = 0;
6882 ioc->alt_ioc->taskmgmt_quiesce_io = 0; 6882 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6883 } 6883 }
6884 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6884 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6885 } 6885 }
6886 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag); 6886 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6887 6887
6888 6888
6889 /** 6889 /**
6890 * mpt_halt_firmware - Halts the firmware if it is operational and panic 6890 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6891 * the kernel 6891 * the kernel
6892 * @ioc: Pointer to MPT_ADAPTER structure 6892 * @ioc: Pointer to MPT_ADAPTER structure
6893 * 6893 *
6894 **/ 6894 **/
6895 void 6895 void
6896 mpt_halt_firmware(MPT_ADAPTER *ioc) 6896 mpt_halt_firmware(MPT_ADAPTER *ioc)
6897 { 6897 {
6898 u32 ioc_raw_state; 6898 u32 ioc_raw_state;
6899 6899
6900 ioc_raw_state = mpt_GetIocState(ioc, 0); 6900 ioc_raw_state = mpt_GetIocState(ioc, 0);
6901 6901
6902 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 6902 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6903 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n", 6903 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6904 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); 6904 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6905 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name, 6905 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6906 ioc_raw_state & MPI_DOORBELL_DATA_MASK); 6906 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6907 } else { 6907 } else {
6908 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00); 6908 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6909 panic("%s: Firmware is halted due to command timeout\n", 6909 panic("%s: Firmware is halted due to command timeout\n",
6910 ioc->name); 6910 ioc->name);
6911 } 6911 }
6912 } 6912 }
6913 EXPORT_SYMBOL(mpt_halt_firmware); 6913 EXPORT_SYMBOL(mpt_halt_firmware);
6914 6914
6915 /** 6915 /**
6916 * mpt_SoftResetHandler - Issues a less expensive reset 6916 * mpt_SoftResetHandler - Issues a less expensive reset
6917 * @ioc: Pointer to MPT_ADAPTER structure 6917 * @ioc: Pointer to MPT_ADAPTER structure
6918 * @sleepFlag: Indicates if sleep or schedule must be called. 6918 * @sleepFlag: Indicates if sleep or schedule must be called.
6919 6919
6920 * 6920 *
6921 * Returns 0 for SUCCESS or -1 if FAILED. 6921 * Returns 0 for SUCCESS or -1 if FAILED.
6922 * 6922 *
6923 * Message Unit Reset - instructs the IOC to reset the Reply Post and 6923 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6924 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded. 6924 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6925 * All posted buffers are freed, and event notification is turned off. 6925 * All posted buffers are freed, and event notification is turned off.
6926 * IOC doesnt reply to any outstanding request. This will transfer IOC 6926 * IOC doesnt reply to any outstanding request. This will transfer IOC
6927 * to READY state. 6927 * to READY state.
6928 **/ 6928 **/
6929 int 6929 int
6930 mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag) 6930 mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6931 { 6931 {
6932 int rc; 6932 int rc;
6933 int ii; 6933 int ii;
6934 u8 cb_idx; 6934 u8 cb_idx;
6935 unsigned long flags; 6935 unsigned long flags;
6936 u32 ioc_state; 6936 u32 ioc_state;
6937 unsigned long time_count; 6937 unsigned long time_count;
6938 6938
6939 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n", 6939 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
6940 ioc->name)); 6940 ioc->name));
6941 6941
6942 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK; 6942 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6943 6943
6944 if (mpt_fwfault_debug) 6944 if (mpt_fwfault_debug)
6945 mpt_halt_firmware(ioc); 6945 mpt_halt_firmware(ioc);
6946 6946
6947 if (ioc_state == MPI_IOC_STATE_FAULT || 6947 if (ioc_state == MPI_IOC_STATE_FAULT ||
6948 ioc_state == MPI_IOC_STATE_RESET) { 6948 ioc_state == MPI_IOC_STATE_RESET) {
6949 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6949 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6950 "skipping, either in FAULT or RESET state!\n", ioc->name)); 6950 "skipping, either in FAULT or RESET state!\n", ioc->name));
6951 return -1; 6951 return -1;
6952 } 6952 }
6953 6953
6954 if (ioc->bus_type == FC) { 6954 if (ioc->bus_type == FC) {
6955 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6955 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6956 "skipping, because the bus type is FC!\n", ioc->name)); 6956 "skipping, because the bus type is FC!\n", ioc->name));
6957 return -1; 6957 return -1;
6958 } 6958 }
6959 6959
6960 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6960 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6961 if (ioc->ioc_reset_in_progress) { 6961 if (ioc->ioc_reset_in_progress) {
6962 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6962 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6963 return -1; 6963 return -1;
6964 } 6964 }
6965 ioc->ioc_reset_in_progress = 1; 6965 ioc->ioc_reset_in_progress = 1;
6966 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6966 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6967 6967
6968 rc = -1; 6968 rc = -1;
6969 6969
6970 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6970 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6971 if (MptResetHandlers[cb_idx]) 6971 if (MptResetHandlers[cb_idx])
6972 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET); 6972 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6973 } 6973 }
6974 6974
6975 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6975 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6976 if (ioc->taskmgmt_in_progress) { 6976 if (ioc->taskmgmt_in_progress) {
6977 ioc->ioc_reset_in_progress = 0;
6977 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6978 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6978 return -1; 6979 return -1;
6979 } 6980 }
6980 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6981 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6981 /* Disable reply interrupts (also blocks FreeQ) */ 6982 /* Disable reply interrupts (also blocks FreeQ) */
6982 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 6983 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
6983 ioc->active = 0; 6984 ioc->active = 0;
6984 time_count = jiffies; 6985 time_count = jiffies;
6985 6986
6986 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag); 6987 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
6987 6988
6988 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6989 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6989 if (MptResetHandlers[cb_idx]) 6990 if (MptResetHandlers[cb_idx])
6990 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET); 6991 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
6991 } 6992 }
6992 6993
6993 if (rc) 6994 if (rc)
6994 goto out; 6995 goto out;
6995 6996
6996 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK; 6997 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6997 if (ioc_state != MPI_IOC_STATE_READY) 6998 if (ioc_state != MPI_IOC_STATE_READY)
6998 goto out; 6999 goto out;
6999 7000
7000 for (ii = 0; ii < 5; ii++) { 7001 for (ii = 0; ii < 5; ii++) {
7001 /* Get IOC facts! Allow 5 retries */ 7002 /* Get IOC facts! Allow 5 retries */
7002 rc = GetIocFacts(ioc, sleepFlag, 7003 rc = GetIocFacts(ioc, sleepFlag,
7003 MPT_HOSTEVENT_IOC_RECOVER); 7004 MPT_HOSTEVENT_IOC_RECOVER);
7004 if (rc == 0) 7005 if (rc == 0)
7005 break; 7006 break;
7006 if (sleepFlag == CAN_SLEEP) 7007 if (sleepFlag == CAN_SLEEP)
7007 msleep(100); 7008 msleep(100);
7008 else 7009 else
7009 mdelay(100); 7010 mdelay(100);
7010 } 7011 }
7011 if (ii == 5) 7012 if (ii == 5)
7012 goto out; 7013 goto out;
7013 7014
7014 rc = PrimeIocFifos(ioc); 7015 rc = PrimeIocFifos(ioc);
7015 if (rc != 0) 7016 if (rc != 0)
7016 goto out; 7017 goto out;
7017 7018
7018 rc = SendIocInit(ioc, sleepFlag); 7019 rc = SendIocInit(ioc, sleepFlag);
7019 if (rc != 0) 7020 if (rc != 0)
7020 goto out; 7021 goto out;
7021 7022
7022 rc = SendEventNotification(ioc, 1, sleepFlag); 7023 rc = SendEventNotification(ioc, 1, sleepFlag);
7023 if (rc != 0) 7024 if (rc != 0)
7024 goto out; 7025 goto out;
7025 7026
7026 if (ioc->hard_resets < -1) 7027 if (ioc->hard_resets < -1)
7027 ioc->hard_resets++; 7028 ioc->hard_resets++;
7028 7029
7029 /* 7030 /*
7030 * At this point, we know soft reset succeeded. 7031 * At this point, we know soft reset succeeded.
7031 */ 7032 */
7032 7033
7033 ioc->active = 1; 7034 ioc->active = 1;
7034 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); 7035 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7035 7036
7036 out: 7037 out:
7037 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 7038 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7038 ioc->ioc_reset_in_progress = 0; 7039 ioc->ioc_reset_in_progress = 0;
7039 ioc->taskmgmt_quiesce_io = 0; 7040 ioc->taskmgmt_quiesce_io = 0;
7040 ioc->taskmgmt_in_progress = 0; 7041 ioc->taskmgmt_in_progress = 0;
7041 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 7042 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7042 7043
7043 if (ioc->active) { /* otherwise, hard reset coming */ 7044 if (ioc->active) { /* otherwise, hard reset coming */
7044 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 7045 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7045 if (MptResetHandlers[cb_idx]) 7046 if (MptResetHandlers[cb_idx])
7046 mpt_signal_reset(cb_idx, ioc, 7047 mpt_signal_reset(cb_idx, ioc,
7047 MPT_IOC_POST_RESET); 7048 MPT_IOC_POST_RESET);
7048 } 7049 }
7049 } 7050 }
7050 7051
7051 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7052 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7052 "SoftResetHandler: completed (%d seconds): %s\n", 7053 "SoftResetHandler: completed (%d seconds): %s\n",
7053 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000, 7054 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7054 ((rc == 0) ? "SUCCESS" : "FAILED"))); 7055 ((rc == 0) ? "SUCCESS" : "FAILED")));
7055 7056
7056 return rc; 7057 return rc;
7057 } 7058 }
7058 7059
7059 /** 7060 /**
7060 * mpt_Soft_Hard_ResetHandler - Try less expensive reset 7061 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7061 * @ioc: Pointer to MPT_ADAPTER structure 7062 * @ioc: Pointer to MPT_ADAPTER structure
7062 * @sleepFlag: Indicates if sleep or schedule must be called. 7063 * @sleepFlag: Indicates if sleep or schedule must be called.
7063 7064
7064 * 7065 *
7065 * Returns 0 for SUCCESS or -1 if FAILED. 7066 * Returns 0 for SUCCESS or -1 if FAILED.
7066 * Try for softreset first, only if it fails go for expensive 7067 * Try for softreset first, only if it fails go for expensive
7067 * HardReset. 7068 * HardReset.
7068 **/ 7069 **/
7069 int 7070 int
7070 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) { 7071 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7071 int ret = -1; 7072 int ret = -1;
7072 7073
7073 ret = mpt_SoftResetHandler(ioc, sleepFlag); 7074 ret = mpt_SoftResetHandler(ioc, sleepFlag);
7074 if (ret == 0) 7075 if (ret == 0)
7075 return ret; 7076 return ret;
7076 ret = mpt_HardResetHandler(ioc, sleepFlag); 7077 ret = mpt_HardResetHandler(ioc, sleepFlag);
7077 return ret; 7078 return ret;
7078 } 7079 }
7079 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler); 7080 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7080 7081
7081 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7082 /* 7083 /*
7083 * Reset Handling 7084 * Reset Handling
7084 */ 7085 */
7085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7086 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7086 /** 7087 /**
7087 * mpt_HardResetHandler - Generic reset handler 7088 * mpt_HardResetHandler - Generic reset handler
7088 * @ioc: Pointer to MPT_ADAPTER structure 7089 * @ioc: Pointer to MPT_ADAPTER structure
7089 * @sleepFlag: Indicates if sleep or schedule must be called. 7090 * @sleepFlag: Indicates if sleep or schedule must be called.
7090 * 7091 *
7091 * Issues SCSI Task Management call based on input arg values. 7092 * Issues SCSI Task Management call based on input arg values.
7092 * If TaskMgmt fails, returns associated SCSI request. 7093 * If TaskMgmt fails, returns associated SCSI request.
7093 * 7094 *
7094 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer) 7095 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7095 * or a non-interrupt thread. In the former, must not call schedule(). 7096 * or a non-interrupt thread. In the former, must not call schedule().
7096 * 7097 *
7097 * Note: A return of -1 is a FATAL error case, as it means a 7098 * Note: A return of -1 is a FATAL error case, as it means a
7098 * FW reload/initialization failed. 7099 * FW reload/initialization failed.
7099 * 7100 *
7100 * Returns 0 for SUCCESS or -1 if FAILED. 7101 * Returns 0 for SUCCESS or -1 if FAILED.
7101 */ 7102 */
7102 int 7103 int
7103 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) 7104 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7104 { 7105 {
7105 int rc; 7106 int rc;
7106 u8 cb_idx; 7107 u8 cb_idx;
7107 unsigned long flags; 7108 unsigned long flags;
7108 unsigned long time_count; 7109 unsigned long time_count;
7109 7110
7110 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name)); 7111 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7111 #ifdef MFCNT 7112 #ifdef MFCNT
7112 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name); 7113 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7113 printk("MF count 0x%x !\n", ioc->mfcnt); 7114 printk("MF count 0x%x !\n", ioc->mfcnt);
7114 #endif 7115 #endif
7115 if (mpt_fwfault_debug) 7116 if (mpt_fwfault_debug)
7116 mpt_halt_firmware(ioc); 7117 mpt_halt_firmware(ioc);
7117 7118
7118 /* Reset the adapter. Prevent more than 1 call to 7119 /* Reset the adapter. Prevent more than 1 call to
7119 * mpt_do_ioc_recovery at any instant in time. 7120 * mpt_do_ioc_recovery at any instant in time.
7120 */ 7121 */
7121 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 7122 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7122 if (ioc->ioc_reset_in_progress) { 7123 if (ioc->ioc_reset_in_progress) {
7123 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 7124 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7124 return 0; 7125 return 0;
7125 } 7126 }
7126 ioc->ioc_reset_in_progress = 1; 7127 ioc->ioc_reset_in_progress = 1;
7127 if (ioc->alt_ioc) 7128 if (ioc->alt_ioc)
7128 ioc->alt_ioc->ioc_reset_in_progress = 1; 7129 ioc->alt_ioc->ioc_reset_in_progress = 1;
7129 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 7130 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7130 7131
7131 7132
7132 /* The SCSI driver needs to adjust timeouts on all current 7133 /* The SCSI driver needs to adjust timeouts on all current
7133 * commands prior to the diagnostic reset being issued. 7134 * commands prior to the diagnostic reset being issued.
7134 * Prevents timeouts occurring during a diagnostic reset...very bad. 7135 * Prevents timeouts occurring during a diagnostic reset...very bad.
7135 * For all other protocol drivers, this is a no-op. 7136 * For all other protocol drivers, this is a no-op.
7136 */ 7137 */
7137 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 7138 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7138 if (MptResetHandlers[cb_idx]) { 7139 if (MptResetHandlers[cb_idx]) {
7139 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET); 7140 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7140 if (ioc->alt_ioc) 7141 if (ioc->alt_ioc)
7141 mpt_signal_reset(cb_idx, ioc->alt_ioc, 7142 mpt_signal_reset(cb_idx, ioc->alt_ioc,
7142 MPT_IOC_SETUP_RESET); 7143 MPT_IOC_SETUP_RESET);
7143 } 7144 }
7144 } 7145 }
7145 7146
7146 time_count = jiffies; 7147 time_count = jiffies;
7147 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag); 7148 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7148 if (rc != 0) { 7149 if (rc != 0) {
7149 printk(KERN_WARNING MYNAM 7150 printk(KERN_WARNING MYNAM
7150 ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name); 7151 ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name);
7151 } else { 7152 } else {
7152 if (ioc->hard_resets < -1) 7153 if (ioc->hard_resets < -1)
7153 ioc->hard_resets++; 7154 ioc->hard_resets++;
7154 } 7155 }
7155 7156
7156 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 7157 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7157 ioc->ioc_reset_in_progress = 0; 7158 ioc->ioc_reset_in_progress = 0;
7158 ioc->taskmgmt_quiesce_io = 0; 7159 ioc->taskmgmt_quiesce_io = 0;
7159 ioc->taskmgmt_in_progress = 0; 7160 ioc->taskmgmt_in_progress = 0;
7160 if (ioc->alt_ioc) { 7161 if (ioc->alt_ioc) {
7161 ioc->alt_ioc->ioc_reset_in_progress = 0; 7162 ioc->alt_ioc->ioc_reset_in_progress = 0;
7162 ioc->alt_ioc->taskmgmt_quiesce_io = 0; 7163 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7163 ioc->alt_ioc->taskmgmt_in_progress = 0; 7164 ioc->alt_ioc->taskmgmt_in_progress = 0;
7164 } 7165 }
7165 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 7166 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7166 7167
7167 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 7168 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7168 if (MptResetHandlers[cb_idx]) { 7169 if (MptResetHandlers[cb_idx]) {
7169 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET); 7170 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7170 if (ioc->alt_ioc) 7171 if (ioc->alt_ioc)
7171 mpt_signal_reset(cb_idx, 7172 mpt_signal_reset(cb_idx,
7172 ioc->alt_ioc, MPT_IOC_POST_RESET); 7173 ioc->alt_ioc, MPT_IOC_POST_RESET);
7173 } 7174 }
7174 } 7175 }
7175 7176
7176 dtmprintk(ioc, 7177 dtmprintk(ioc,
7177 printk(MYIOC_s_DEBUG_FMT 7178 printk(MYIOC_s_DEBUG_FMT
7178 "HardResetHandler: completed (%d seconds): %s\n", ioc->name, 7179 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7179 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ? 7180 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7180 "SUCCESS" : "FAILED"))); 7181 "SUCCESS" : "FAILED")));
7181 7182
7182 return rc; 7183 return rc;
7183 } 7184 }
7184 7185
7185 #ifdef CONFIG_FUSION_LOGGING 7186 #ifdef CONFIG_FUSION_LOGGING
7186 static void 7187 static void
7187 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply) 7188 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7188 { 7189 {
7189 char *ds = NULL; 7190 char *ds = NULL;
7190 u32 evData0; 7191 u32 evData0;
7191 int ii; 7192 int ii;
7192 u8 event; 7193 u8 event;
7193 char *evStr = ioc->evStr; 7194 char *evStr = ioc->evStr;
7194 7195
7195 event = le32_to_cpu(pEventReply->Event) & 0xFF; 7196 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7196 evData0 = le32_to_cpu(pEventReply->Data[0]); 7197 evData0 = le32_to_cpu(pEventReply->Data[0]);
7197 7198
7198 switch(event) { 7199 switch(event) {
7199 case MPI_EVENT_NONE: 7200 case MPI_EVENT_NONE:
7200 ds = "None"; 7201 ds = "None";
7201 break; 7202 break;
7202 case MPI_EVENT_LOG_DATA: 7203 case MPI_EVENT_LOG_DATA:
7203 ds = "Log Data"; 7204 ds = "Log Data";
7204 break; 7205 break;
7205 case MPI_EVENT_STATE_CHANGE: 7206 case MPI_EVENT_STATE_CHANGE:
7206 ds = "State Change"; 7207 ds = "State Change";
7207 break; 7208 break;
7208 case MPI_EVENT_UNIT_ATTENTION: 7209 case MPI_EVENT_UNIT_ATTENTION:
7209 ds = "Unit Attention"; 7210 ds = "Unit Attention";
7210 break; 7211 break;
7211 case MPI_EVENT_IOC_BUS_RESET: 7212 case MPI_EVENT_IOC_BUS_RESET:
7212 ds = "IOC Bus Reset"; 7213 ds = "IOC Bus Reset";
7213 break; 7214 break;
7214 case MPI_EVENT_EXT_BUS_RESET: 7215 case MPI_EVENT_EXT_BUS_RESET:
7215 ds = "External Bus Reset"; 7216 ds = "External Bus Reset";
7216 break; 7217 break;
7217 case MPI_EVENT_RESCAN: 7218 case MPI_EVENT_RESCAN:
7218 ds = "Bus Rescan Event"; 7219 ds = "Bus Rescan Event";
7219 break; 7220 break;
7220 case MPI_EVENT_LINK_STATUS_CHANGE: 7221 case MPI_EVENT_LINK_STATUS_CHANGE:
7221 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE) 7222 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7222 ds = "Link Status(FAILURE) Change"; 7223 ds = "Link Status(FAILURE) Change";
7223 else 7224 else
7224 ds = "Link Status(ACTIVE) Change"; 7225 ds = "Link Status(ACTIVE) Change";
7225 break; 7226 break;
7226 case MPI_EVENT_LOOP_STATE_CHANGE: 7227 case MPI_EVENT_LOOP_STATE_CHANGE:
7227 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP) 7228 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7228 ds = "Loop State(LIP) Change"; 7229 ds = "Loop State(LIP) Change";
7229 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE) 7230 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7230 ds = "Loop State(LPE) Change"; 7231 ds = "Loop State(LPE) Change";
7231 else 7232 else
7232 ds = "Loop State(LPB) Change"; 7233 ds = "Loop State(LPB) Change";
7233 break; 7234 break;
7234 case MPI_EVENT_LOGOUT: 7235 case MPI_EVENT_LOGOUT:
7235 ds = "Logout"; 7236 ds = "Logout";
7236 break; 7237 break;
7237 case MPI_EVENT_EVENT_CHANGE: 7238 case MPI_EVENT_EVENT_CHANGE:
7238 if (evData0) 7239 if (evData0)
7239 ds = "Events ON"; 7240 ds = "Events ON";
7240 else 7241 else
7241 ds = "Events OFF"; 7242 ds = "Events OFF";
7242 break; 7243 break;
7243 case MPI_EVENT_INTEGRATED_RAID: 7244 case MPI_EVENT_INTEGRATED_RAID:
7244 { 7245 {
7245 u8 ReasonCode = (u8)(evData0 >> 16); 7246 u8 ReasonCode = (u8)(evData0 >> 16);
7246 switch (ReasonCode) { 7247 switch (ReasonCode) {
7247 case MPI_EVENT_RAID_RC_VOLUME_CREATED : 7248 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7248 ds = "Integrated Raid: Volume Created"; 7249 ds = "Integrated Raid: Volume Created";
7249 break; 7250 break;
7250 case MPI_EVENT_RAID_RC_VOLUME_DELETED : 7251 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7251 ds = "Integrated Raid: Volume Deleted"; 7252 ds = "Integrated Raid: Volume Deleted";
7252 break; 7253 break;
7253 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED : 7254 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7254 ds = "Integrated Raid: Volume Settings Changed"; 7255 ds = "Integrated Raid: Volume Settings Changed";
7255 break; 7256 break;
7256 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED : 7257 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7257 ds = "Integrated Raid: Volume Status Changed"; 7258 ds = "Integrated Raid: Volume Status Changed";
7258 break; 7259 break;
7259 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED : 7260 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7260 ds = "Integrated Raid: Volume Physdisk Changed"; 7261 ds = "Integrated Raid: Volume Physdisk Changed";
7261 break; 7262 break;
7262 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED : 7263 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7263 ds = "Integrated Raid: Physdisk Created"; 7264 ds = "Integrated Raid: Physdisk Created";
7264 break; 7265 break;
7265 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED : 7266 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7266 ds = "Integrated Raid: Physdisk Deleted"; 7267 ds = "Integrated Raid: Physdisk Deleted";
7267 break; 7268 break;
7268 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED : 7269 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7269 ds = "Integrated Raid: Physdisk Settings Changed"; 7270 ds = "Integrated Raid: Physdisk Settings Changed";
7270 break; 7271 break;
7271 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED : 7272 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7272 ds = "Integrated Raid: Physdisk Status Changed"; 7273 ds = "Integrated Raid: Physdisk Status Changed";
7273 break; 7274 break;
7274 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED : 7275 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7275 ds = "Integrated Raid: Domain Validation Needed"; 7276 ds = "Integrated Raid: Domain Validation Needed";
7276 break; 7277 break;
7277 case MPI_EVENT_RAID_RC_SMART_DATA : 7278 case MPI_EVENT_RAID_RC_SMART_DATA :
7278 ds = "Integrated Raid; Smart Data"; 7279 ds = "Integrated Raid; Smart Data";
7279 break; 7280 break;
7280 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED : 7281 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7281 ds = "Integrated Raid: Replace Action Started"; 7282 ds = "Integrated Raid: Replace Action Started";
7282 break; 7283 break;
7283 default: 7284 default:
7284 ds = "Integrated Raid"; 7285 ds = "Integrated Raid";
7285 break; 7286 break;
7286 } 7287 }
7287 break; 7288 break;
7288 } 7289 }
7289 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: 7290 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7290 ds = "SCSI Device Status Change"; 7291 ds = "SCSI Device Status Change";
7291 break; 7292 break;
7292 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 7293 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7293 { 7294 {
7294 u8 id = (u8)(evData0); 7295 u8 id = (u8)(evData0);
7295 u8 channel = (u8)(evData0 >> 8); 7296 u8 channel = (u8)(evData0 >> 8);
7296 u8 ReasonCode = (u8)(evData0 >> 16); 7297 u8 ReasonCode = (u8)(evData0 >> 16);
7297 switch (ReasonCode) { 7298 switch (ReasonCode) {
7298 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: 7299 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7299 snprintf(evStr, EVENT_DESCR_STR_SZ, 7300 snprintf(evStr, EVENT_DESCR_STR_SZ,
7300 "SAS Device Status Change: Added: " 7301 "SAS Device Status Change: Added: "
7301 "id=%d channel=%d", id, channel); 7302 "id=%d channel=%d", id, channel);
7302 break; 7303 break;
7303 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: 7304 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7304 snprintf(evStr, EVENT_DESCR_STR_SZ, 7305 snprintf(evStr, EVENT_DESCR_STR_SZ,
7305 "SAS Device Status Change: Deleted: " 7306 "SAS Device Status Change: Deleted: "
7306 "id=%d channel=%d", id, channel); 7307 "id=%d channel=%d", id, channel);
7307 break; 7308 break;
7308 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 7309 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7309 snprintf(evStr, EVENT_DESCR_STR_SZ, 7310 snprintf(evStr, EVENT_DESCR_STR_SZ,
7310 "SAS Device Status Change: SMART Data: " 7311 "SAS Device Status Change: SMART Data: "
7311 "id=%d channel=%d", id, channel); 7312 "id=%d channel=%d", id, channel);
7312 break; 7313 break;
7313 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: 7314 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7314 snprintf(evStr, EVENT_DESCR_STR_SZ, 7315 snprintf(evStr, EVENT_DESCR_STR_SZ,
7315 "SAS Device Status Change: No Persistancy: " 7316 "SAS Device Status Change: No Persistancy: "
7316 "id=%d channel=%d", id, channel); 7317 "id=%d channel=%d", id, channel);
7317 break; 7318 break;
7318 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 7319 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7319 snprintf(evStr, EVENT_DESCR_STR_SZ, 7320 snprintf(evStr, EVENT_DESCR_STR_SZ,
7320 "SAS Device Status Change: Unsupported Device " 7321 "SAS Device Status Change: Unsupported Device "
7321 "Discovered : id=%d channel=%d", id, channel); 7322 "Discovered : id=%d channel=%d", id, channel);
7322 break; 7323 break;
7323 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 7324 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7324 snprintf(evStr, EVENT_DESCR_STR_SZ, 7325 snprintf(evStr, EVENT_DESCR_STR_SZ,
7325 "SAS Device Status Change: Internal Device " 7326 "SAS Device Status Change: Internal Device "
7326 "Reset : id=%d channel=%d", id, channel); 7327 "Reset : id=%d channel=%d", id, channel);
7327 break; 7328 break;
7328 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 7329 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7329 snprintf(evStr, EVENT_DESCR_STR_SZ, 7330 snprintf(evStr, EVENT_DESCR_STR_SZ,
7330 "SAS Device Status Change: Internal Task " 7331 "SAS Device Status Change: Internal Task "
7331 "Abort : id=%d channel=%d", id, channel); 7332 "Abort : id=%d channel=%d", id, channel);
7332 break; 7333 break;
7333 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 7334 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7334 snprintf(evStr, EVENT_DESCR_STR_SZ, 7335 snprintf(evStr, EVENT_DESCR_STR_SZ,
7335 "SAS Device Status Change: Internal Abort " 7336 "SAS Device Status Change: Internal Abort "
7336 "Task Set : id=%d channel=%d", id, channel); 7337 "Task Set : id=%d channel=%d", id, channel);
7337 break; 7338 break;
7338 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 7339 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7339 snprintf(evStr, EVENT_DESCR_STR_SZ, 7340 snprintf(evStr, EVENT_DESCR_STR_SZ,
7340 "SAS Device Status Change: Internal Clear " 7341 "SAS Device Status Change: Internal Clear "
7341 "Task Set : id=%d channel=%d", id, channel); 7342 "Task Set : id=%d channel=%d", id, channel);
7342 break; 7343 break;
7343 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 7344 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7344 snprintf(evStr, EVENT_DESCR_STR_SZ, 7345 snprintf(evStr, EVENT_DESCR_STR_SZ,
7345 "SAS Device Status Change: Internal Query " 7346 "SAS Device Status Change: Internal Query "
7346 "Task : id=%d channel=%d", id, channel); 7347 "Task : id=%d channel=%d", id, channel);
7347 break; 7348 break;
7348 default: 7349 default:
7349 snprintf(evStr, EVENT_DESCR_STR_SZ, 7350 snprintf(evStr, EVENT_DESCR_STR_SZ,
7350 "SAS Device Status Change: Unknown: " 7351 "SAS Device Status Change: Unknown: "
7351 "id=%d channel=%d", id, channel); 7352 "id=%d channel=%d", id, channel);
7352 break; 7353 break;
7353 } 7354 }
7354 break; 7355 break;
7355 } 7356 }
7356 case MPI_EVENT_ON_BUS_TIMER_EXPIRED: 7357 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7357 ds = "Bus Timer Expired"; 7358 ds = "Bus Timer Expired";
7358 break; 7359 break;
7359 case MPI_EVENT_QUEUE_FULL: 7360 case MPI_EVENT_QUEUE_FULL:
7360 { 7361 {
7361 u16 curr_depth = (u16)(evData0 >> 16); 7362 u16 curr_depth = (u16)(evData0 >> 16);
7362 u8 channel = (u8)(evData0 >> 8); 7363 u8 channel = (u8)(evData0 >> 8);
7363 u8 id = (u8)(evData0); 7364 u8 id = (u8)(evData0);
7364 7365
7365 snprintf(evStr, EVENT_DESCR_STR_SZ, 7366 snprintf(evStr, EVENT_DESCR_STR_SZ,
7366 "Queue Full: channel=%d id=%d depth=%d", 7367 "Queue Full: channel=%d id=%d depth=%d",
7367 channel, id, curr_depth); 7368 channel, id, curr_depth);
7368 break; 7369 break;
7369 } 7370 }
7370 case MPI_EVENT_SAS_SES: 7371 case MPI_EVENT_SAS_SES:
7371 ds = "SAS SES Event"; 7372 ds = "SAS SES Event";
7372 break; 7373 break;
7373 case MPI_EVENT_PERSISTENT_TABLE_FULL: 7374 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7374 ds = "Persistent Table Full"; 7375 ds = "Persistent Table Full";
7375 break; 7376 break;
7376 case MPI_EVENT_SAS_PHY_LINK_STATUS: 7377 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7377 { 7378 {
7378 u8 LinkRates = (u8)(evData0 >> 8); 7379 u8 LinkRates = (u8)(evData0 >> 8);
7379 u8 PhyNumber = (u8)(evData0); 7380 u8 PhyNumber = (u8)(evData0);
7380 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >> 7381 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7381 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT; 7382 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7382 switch (LinkRates) { 7383 switch (LinkRates) {
7383 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN: 7384 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7384 snprintf(evStr, EVENT_DESCR_STR_SZ, 7385 snprintf(evStr, EVENT_DESCR_STR_SZ,
7385 "SAS PHY Link Status: Phy=%d:" 7386 "SAS PHY Link Status: Phy=%d:"
7386 " Rate Unknown",PhyNumber); 7387 " Rate Unknown",PhyNumber);
7387 break; 7388 break;
7388 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED: 7389 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7389 snprintf(evStr, EVENT_DESCR_STR_SZ, 7390 snprintf(evStr, EVENT_DESCR_STR_SZ,
7390 "SAS PHY Link Status: Phy=%d:" 7391 "SAS PHY Link Status: Phy=%d:"
7391 " Phy Disabled",PhyNumber); 7392 " Phy Disabled",PhyNumber);
7392 break; 7393 break;
7393 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION: 7394 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7394 snprintf(evStr, EVENT_DESCR_STR_SZ, 7395 snprintf(evStr, EVENT_DESCR_STR_SZ,
7395 "SAS PHY Link Status: Phy=%d:" 7396 "SAS PHY Link Status: Phy=%d:"
7396 " Failed Speed Nego",PhyNumber); 7397 " Failed Speed Nego",PhyNumber);
7397 break; 7398 break;
7398 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE: 7399 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7399 snprintf(evStr, EVENT_DESCR_STR_SZ, 7400 snprintf(evStr, EVENT_DESCR_STR_SZ,
7400 "SAS PHY Link Status: Phy=%d:" 7401 "SAS PHY Link Status: Phy=%d:"
7401 " Sata OOB Completed",PhyNumber); 7402 " Sata OOB Completed",PhyNumber);
7402 break; 7403 break;
7403 case MPI_EVENT_SAS_PLS_LR_RATE_1_5: 7404 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7404 snprintf(evStr, EVENT_DESCR_STR_SZ, 7405 snprintf(evStr, EVENT_DESCR_STR_SZ,
7405 "SAS PHY Link Status: Phy=%d:" 7406 "SAS PHY Link Status: Phy=%d:"
7406 " Rate 1.5 Gbps",PhyNumber); 7407 " Rate 1.5 Gbps",PhyNumber);
7407 break; 7408 break;
7408 case MPI_EVENT_SAS_PLS_LR_RATE_3_0: 7409 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7409 snprintf(evStr, EVENT_DESCR_STR_SZ, 7410 snprintf(evStr, EVENT_DESCR_STR_SZ,
7410 "SAS PHY Link Status: Phy=%d:" 7411 "SAS PHY Link Status: Phy=%d:"
7411 " Rate 3.0 Gpbs",PhyNumber); 7412 " Rate 3.0 Gpbs",PhyNumber);
7412 break; 7413 break;
7413 default: 7414 default:
7414 snprintf(evStr, EVENT_DESCR_STR_SZ, 7415 snprintf(evStr, EVENT_DESCR_STR_SZ,
7415 "SAS PHY Link Status: Phy=%d", PhyNumber); 7416 "SAS PHY Link Status: Phy=%d", PhyNumber);
7416 break; 7417 break;
7417 } 7418 }
7418 break; 7419 break;
7419 } 7420 }
7420 case MPI_EVENT_SAS_DISCOVERY_ERROR: 7421 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7421 ds = "SAS Discovery Error"; 7422 ds = "SAS Discovery Error";
7422 break; 7423 break;
7423 case MPI_EVENT_IR_RESYNC_UPDATE: 7424 case MPI_EVENT_IR_RESYNC_UPDATE:
7424 { 7425 {
7425 u8 resync_complete = (u8)(evData0 >> 16); 7426 u8 resync_complete = (u8)(evData0 >> 16);
7426 snprintf(evStr, EVENT_DESCR_STR_SZ, 7427 snprintf(evStr, EVENT_DESCR_STR_SZ,
7427 "IR Resync Update: Complete = %d:",resync_complete); 7428 "IR Resync Update: Complete = %d:",resync_complete);
7428 break; 7429 break;
7429 } 7430 }
7430 case MPI_EVENT_IR2: 7431 case MPI_EVENT_IR2:
7431 { 7432 {
7432 u8 id = (u8)(evData0); 7433 u8 id = (u8)(evData0);
7433 u8 channel = (u8)(evData0 >> 8); 7434 u8 channel = (u8)(evData0 >> 8);
7434 u8 phys_num = (u8)(evData0 >> 24); 7435 u8 phys_num = (u8)(evData0 >> 24);
7435 u8 ReasonCode = (u8)(evData0 >> 16); 7436 u8 ReasonCode = (u8)(evData0 >> 16);
7436 7437
7437 switch (ReasonCode) { 7438 switch (ReasonCode) {
7438 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED: 7439 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7439 snprintf(evStr, EVENT_DESCR_STR_SZ, 7440 snprintf(evStr, EVENT_DESCR_STR_SZ,
7440 "IR2: LD State Changed: " 7441 "IR2: LD State Changed: "
7441 "id=%d channel=%d phys_num=%d", 7442 "id=%d channel=%d phys_num=%d",
7442 id, channel, phys_num); 7443 id, channel, phys_num);
7443 break; 7444 break;
7444 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED: 7445 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7445 snprintf(evStr, EVENT_DESCR_STR_SZ, 7446 snprintf(evStr, EVENT_DESCR_STR_SZ,
7446 "IR2: PD State Changed " 7447 "IR2: PD State Changed "
7447 "id=%d channel=%d phys_num=%d", 7448 "id=%d channel=%d phys_num=%d",
7448 id, channel, phys_num); 7449 id, channel, phys_num);
7449 break; 7450 break;
7450 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL: 7451 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7451 snprintf(evStr, EVENT_DESCR_STR_SZ, 7452 snprintf(evStr, EVENT_DESCR_STR_SZ,
7452 "IR2: Bad Block Table Full: " 7453 "IR2: Bad Block Table Full: "
7453 "id=%d channel=%d phys_num=%d", 7454 "id=%d channel=%d phys_num=%d",
7454 id, channel, phys_num); 7455 id, channel, phys_num);
7455 break; 7456 break;
7456 case MPI_EVENT_IR2_RC_PD_INSERTED: 7457 case MPI_EVENT_IR2_RC_PD_INSERTED:
7457 snprintf(evStr, EVENT_DESCR_STR_SZ, 7458 snprintf(evStr, EVENT_DESCR_STR_SZ,
7458 "IR2: PD Inserted: " 7459 "IR2: PD Inserted: "
7459 "id=%d channel=%d phys_num=%d", 7460 "id=%d channel=%d phys_num=%d",
7460 id, channel, phys_num); 7461 id, channel, phys_num);
7461 break; 7462 break;
7462 case MPI_EVENT_IR2_RC_PD_REMOVED: 7463 case MPI_EVENT_IR2_RC_PD_REMOVED:
7463 snprintf(evStr, EVENT_DESCR_STR_SZ, 7464 snprintf(evStr, EVENT_DESCR_STR_SZ,
7464 "IR2: PD Removed: " 7465 "IR2: PD Removed: "
7465 "id=%d channel=%d phys_num=%d", 7466 "id=%d channel=%d phys_num=%d",
7466 id, channel, phys_num); 7467 id, channel, phys_num);
7467 break; 7468 break;
7468 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED: 7469 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7469 snprintf(evStr, EVENT_DESCR_STR_SZ, 7470 snprintf(evStr, EVENT_DESCR_STR_SZ,
7470 "IR2: Foreign CFG Detected: " 7471 "IR2: Foreign CFG Detected: "
7471 "id=%d channel=%d phys_num=%d", 7472 "id=%d channel=%d phys_num=%d",
7472 id, channel, phys_num); 7473 id, channel, phys_num);
7473 break; 7474 break;
7474 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR: 7475 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7475 snprintf(evStr, EVENT_DESCR_STR_SZ, 7476 snprintf(evStr, EVENT_DESCR_STR_SZ,
7476 "IR2: Rebuild Medium Error: " 7477 "IR2: Rebuild Medium Error: "
7477 "id=%d channel=%d phys_num=%d", 7478 "id=%d channel=%d phys_num=%d",
7478 id, channel, phys_num); 7479 id, channel, phys_num);
7479 break; 7480 break;
7480 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED: 7481 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7481 snprintf(evStr, EVENT_DESCR_STR_SZ, 7482 snprintf(evStr, EVENT_DESCR_STR_SZ,
7482 "IR2: Dual Port Added: " 7483 "IR2: Dual Port Added: "
7483 "id=%d channel=%d phys_num=%d", 7484 "id=%d channel=%d phys_num=%d",
7484 id, channel, phys_num); 7485 id, channel, phys_num);
7485 break; 7486 break;
7486 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED: 7487 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7487 snprintf(evStr, EVENT_DESCR_STR_SZ, 7488 snprintf(evStr, EVENT_DESCR_STR_SZ,
7488 "IR2: Dual Port Removed: " 7489 "IR2: Dual Port Removed: "
7489 "id=%d channel=%d phys_num=%d", 7490 "id=%d channel=%d phys_num=%d",
7490 id, channel, phys_num); 7491 id, channel, phys_num);
7491 break; 7492 break;
7492 default: 7493 default:
7493 ds = "IR2"; 7494 ds = "IR2";
7494 break; 7495 break;
7495 } 7496 }
7496 break; 7497 break;
7497 } 7498 }
7498 case MPI_EVENT_SAS_DISCOVERY: 7499 case MPI_EVENT_SAS_DISCOVERY:
7499 { 7500 {
7500 if (evData0) 7501 if (evData0)
7501 ds = "SAS Discovery: Start"; 7502 ds = "SAS Discovery: Start";
7502 else 7503 else
7503 ds = "SAS Discovery: Stop"; 7504 ds = "SAS Discovery: Stop";
7504 break; 7505 break;
7505 } 7506 }
7506 case MPI_EVENT_LOG_ENTRY_ADDED: 7507 case MPI_EVENT_LOG_ENTRY_ADDED:
7507 ds = "SAS Log Entry Added"; 7508 ds = "SAS Log Entry Added";
7508 break; 7509 break;
7509 7510
7510 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE: 7511 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7511 { 7512 {
7512 u8 phy_num = (u8)(evData0); 7513 u8 phy_num = (u8)(evData0);
7513 u8 port_num = (u8)(evData0 >> 8); 7514 u8 port_num = (u8)(evData0 >> 8);
7514 u8 port_width = (u8)(evData0 >> 16); 7515 u8 port_width = (u8)(evData0 >> 16);
7515 u8 primative = (u8)(evData0 >> 24); 7516 u8 primative = (u8)(evData0 >> 24);
7516 snprintf(evStr, EVENT_DESCR_STR_SZ, 7517 snprintf(evStr, EVENT_DESCR_STR_SZ,
7517 "SAS Broadcase Primative: phy=%d port=%d " 7518 "SAS Broadcase Primative: phy=%d port=%d "
7518 "width=%d primative=0x%02x", 7519 "width=%d primative=0x%02x",
7519 phy_num, port_num, port_width, primative); 7520 phy_num, port_num, port_width, primative);
7520 break; 7521 break;
7521 } 7522 }
7522 7523
7523 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: 7524 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7524 { 7525 {
7525 u8 reason = (u8)(evData0); 7526 u8 reason = (u8)(evData0);
7526 7527
7527 switch (reason) { 7528 switch (reason) {
7528 case MPI_EVENT_SAS_INIT_RC_ADDED: 7529 case MPI_EVENT_SAS_INIT_RC_ADDED:
7529 ds = "SAS Initiator Status Change: Added"; 7530 ds = "SAS Initiator Status Change: Added";
7530 break; 7531 break;
7531 case MPI_EVENT_SAS_INIT_RC_REMOVED: 7532 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7532 ds = "SAS Initiator Status Change: Deleted"; 7533 ds = "SAS Initiator Status Change: Deleted";
7533 break; 7534 break;
7534 default: 7535 default:
7535 ds = "SAS Initiator Status Change"; 7536 ds = "SAS Initiator Status Change";
7536 break; 7537 break;
7537 } 7538 }
7538 break; 7539 break;
7539 } 7540 }
7540 7541
7541 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW: 7542 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7542 { 7543 {
7543 u8 max_init = (u8)(evData0); 7544 u8 max_init = (u8)(evData0);
7544 u8 current_init = (u8)(evData0 >> 8); 7545 u8 current_init = (u8)(evData0 >> 8);
7545 7546
7546 snprintf(evStr, EVENT_DESCR_STR_SZ, 7547 snprintf(evStr, EVENT_DESCR_STR_SZ,
7547 "SAS Initiator Device Table Overflow: max initiators=%02d " 7548 "SAS Initiator Device Table Overflow: max initiators=%02d "
7548 "current initators=%02d", 7549 "current initators=%02d",
7549 max_init, current_init); 7550 max_init, current_init);
7550 break; 7551 break;
7551 } 7552 }
7552 case MPI_EVENT_SAS_SMP_ERROR: 7553 case MPI_EVENT_SAS_SMP_ERROR:
7553 { 7554 {
7554 u8 status = (u8)(evData0); 7555 u8 status = (u8)(evData0);
7555 u8 port_num = (u8)(evData0 >> 8); 7556 u8 port_num = (u8)(evData0 >> 8);
7556 u8 result = (u8)(evData0 >> 16); 7557 u8 result = (u8)(evData0 >> 16);
7557 7558
7558 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID) 7559 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7559 snprintf(evStr, EVENT_DESCR_STR_SZ, 7560 snprintf(evStr, EVENT_DESCR_STR_SZ,
7560 "SAS SMP Error: port=%d result=0x%02x", 7561 "SAS SMP Error: port=%d result=0x%02x",
7561 port_num, result); 7562 port_num, result);
7562 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR) 7563 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7563 snprintf(evStr, EVENT_DESCR_STR_SZ, 7564 snprintf(evStr, EVENT_DESCR_STR_SZ,
7564 "SAS SMP Error: port=%d : CRC Error", 7565 "SAS SMP Error: port=%d : CRC Error",
7565 port_num); 7566 port_num);
7566 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT) 7567 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7567 snprintf(evStr, EVENT_DESCR_STR_SZ, 7568 snprintf(evStr, EVENT_DESCR_STR_SZ,
7568 "SAS SMP Error: port=%d : Timeout", 7569 "SAS SMP Error: port=%d : Timeout",
7569 port_num); 7570 port_num);
7570 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION) 7571 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7571 snprintf(evStr, EVENT_DESCR_STR_SZ, 7572 snprintf(evStr, EVENT_DESCR_STR_SZ,
7572 "SAS SMP Error: port=%d : No Destination", 7573 "SAS SMP Error: port=%d : No Destination",
7573 port_num); 7574 port_num);
7574 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION) 7575 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7575 snprintf(evStr, EVENT_DESCR_STR_SZ, 7576 snprintf(evStr, EVENT_DESCR_STR_SZ,
7576 "SAS SMP Error: port=%d : Bad Destination", 7577 "SAS SMP Error: port=%d : Bad Destination",
7577 port_num); 7578 port_num);
7578 else 7579 else
7579 snprintf(evStr, EVENT_DESCR_STR_SZ, 7580 snprintf(evStr, EVENT_DESCR_STR_SZ,
7580 "SAS SMP Error: port=%d : status=0x%02x", 7581 "SAS SMP Error: port=%d : status=0x%02x",
7581 port_num, status); 7582 port_num, status);
7582 break; 7583 break;
7583 } 7584 }
7584 7585
7585 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE: 7586 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7586 { 7587 {
7587 u8 reason = (u8)(evData0); 7588 u8 reason = (u8)(evData0);
7588 7589
7589 switch (reason) { 7590 switch (reason) {
7590 case MPI_EVENT_SAS_EXP_RC_ADDED: 7591 case MPI_EVENT_SAS_EXP_RC_ADDED:
7591 ds = "Expander Status Change: Added"; 7592 ds = "Expander Status Change: Added";
7592 break; 7593 break;
7593 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING: 7594 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7594 ds = "Expander Status Change: Deleted"; 7595 ds = "Expander Status Change: Deleted";
7595 break; 7596 break;
7596 default: 7597 default:
7597 ds = "Expander Status Change"; 7598 ds = "Expander Status Change";
7598 break; 7599 break;
7599 } 7600 }
7600 break; 7601 break;
7601 } 7602 }
7602 7603
7603 /* 7604 /*
7604 * MPT base "custom" events may be added here... 7605 * MPT base "custom" events may be added here...
7605 */ 7606 */
7606 default: 7607 default:
7607 ds = "Unknown"; 7608 ds = "Unknown";
7608 break; 7609 break;
7609 } 7610 }
7610 if (ds) 7611 if (ds)
7611 strncpy(evStr, ds, EVENT_DESCR_STR_SZ); 7612 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7612 7613
7613 7614
7614 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7615 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7615 "MPT event:(%02Xh) : %s\n", 7616 "MPT event:(%02Xh) : %s\n",
7616 ioc->name, event, evStr)); 7617 ioc->name, event, evStr));
7617 7618
7618 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM 7619 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7619 ": Event data:\n")); 7620 ": Event data:\n"));
7620 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++) 7621 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7621 devtverboseprintk(ioc, printk(" %08x", 7622 devtverboseprintk(ioc, printk(" %08x",
7622 le32_to_cpu(pEventReply->Data[ii]))); 7623 le32_to_cpu(pEventReply->Data[ii])));
7623 devtverboseprintk(ioc, printk(KERN_DEBUG "\n")); 7624 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7624 } 7625 }
7625 #endif 7626 #endif
7626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7627 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7627 /** 7628 /**
7628 * ProcessEventNotification - Route EventNotificationReply to all event handlers 7629 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7629 * @ioc: Pointer to MPT_ADAPTER structure 7630 * @ioc: Pointer to MPT_ADAPTER structure
7630 * @pEventReply: Pointer to EventNotification reply frame 7631 * @pEventReply: Pointer to EventNotification reply frame
7631 * @evHandlers: Pointer to integer, number of event handlers 7632 * @evHandlers: Pointer to integer, number of event handlers
7632 * 7633 *
7633 * Routes a received EventNotificationReply to all currently registered 7634 * Routes a received EventNotificationReply to all currently registered
7634 * event handlers. 7635 * event handlers.
7635 * Returns sum of event handlers return values. 7636 * Returns sum of event handlers return values.
7636 */ 7637 */
7637 static int 7638 static int
7638 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers) 7639 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7639 { 7640 {
7640 u16 evDataLen; 7641 u16 evDataLen;
7641 u32 evData0 = 0; 7642 u32 evData0 = 0;
7642 int ii; 7643 int ii;
7643 u8 cb_idx; 7644 u8 cb_idx;
7644 int r = 0; 7645 int r = 0;
7645 int handlers = 0; 7646 int handlers = 0;
7646 u8 event; 7647 u8 event;
7647 7648
7648 /* 7649 /*
7649 * Do platform normalization of values 7650 * Do platform normalization of values
7650 */ 7651 */
7651 event = le32_to_cpu(pEventReply->Event) & 0xFF; 7652 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7652 evDataLen = le16_to_cpu(pEventReply->EventDataLength); 7653 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7653 if (evDataLen) { 7654 if (evDataLen) {
7654 evData0 = le32_to_cpu(pEventReply->Data[0]); 7655 evData0 = le32_to_cpu(pEventReply->Data[0]);
7655 } 7656 }
7656 7657
7657 #ifdef CONFIG_FUSION_LOGGING 7658 #ifdef CONFIG_FUSION_LOGGING
7658 if (evDataLen) 7659 if (evDataLen)
7659 mpt_display_event_info(ioc, pEventReply); 7660 mpt_display_event_info(ioc, pEventReply);
7660 #endif 7661 #endif
7661 7662
7662 /* 7663 /*
7663 * Do general / base driver event processing 7664 * Do general / base driver event processing
7664 */ 7665 */
7665 switch(event) { 7666 switch(event) {
7666 case MPI_EVENT_EVENT_CHANGE: /* 0A */ 7667 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7667 if (evDataLen) { 7668 if (evDataLen) {
7668 u8 evState = evData0 & 0xFF; 7669 u8 evState = evData0 & 0xFF;
7669 7670
7670 /* CHECKME! What if evState unexpectedly says OFF (0)? */ 7671 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7671 7672
7672 /* Update EventState field in cached IocFacts */ 7673 /* Update EventState field in cached IocFacts */
7673 if (ioc->facts.Function) { 7674 if (ioc->facts.Function) {
7674 ioc->facts.EventState = evState; 7675 ioc->facts.EventState = evState;
7675 } 7676 }
7676 } 7677 }
7677 break; 7678 break;
7678 case MPI_EVENT_INTEGRATED_RAID: 7679 case MPI_EVENT_INTEGRATED_RAID:
7679 mptbase_raid_process_event_data(ioc, 7680 mptbase_raid_process_event_data(ioc,
7680 (MpiEventDataRaid_t *)pEventReply->Data); 7681 (MpiEventDataRaid_t *)pEventReply->Data);
7681 break; 7682 break;
7682 default: 7683 default:
7683 break; 7684 break;
7684 } 7685 }
7685 7686
7686 /* 7687 /*
7687 * Should this event be logged? Events are written sequentially. 7688 * Should this event be logged? Events are written sequentially.
7688 * When buffer is full, start again at the top. 7689 * When buffer is full, start again at the top.
7689 */ 7690 */
7690 if (ioc->events && (ioc->eventTypes & ( 1 << event))) { 7691 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7691 int idx; 7692 int idx;
7692 7693
7693 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; 7694 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7694 7695
7695 ioc->events[idx].event = event; 7696 ioc->events[idx].event = event;
7696 ioc->events[idx].eventContext = ioc->eventContext; 7697 ioc->events[idx].eventContext = ioc->eventContext;
7697 7698
7698 for (ii = 0; ii < 2; ii++) { 7699 for (ii = 0; ii < 2; ii++) {
7699 if (ii < evDataLen) 7700 if (ii < evDataLen)
7700 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]); 7701 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7701 else 7702 else
7702 ioc->events[idx].data[ii] = 0; 7703 ioc->events[idx].data[ii] = 0;
7703 } 7704 }
7704 7705
7705 ioc->eventContext++; 7706 ioc->eventContext++;
7706 } 7707 }
7707 7708
7708 7709
7709 /* 7710 /*
7710 * Call each currently registered protocol event handler. 7711 * Call each currently registered protocol event handler.
7711 */ 7712 */
7712 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 7713 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7713 if (MptEvHandlers[cb_idx]) { 7714 if (MptEvHandlers[cb_idx]) {
7714 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7715 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7715 "Routing Event to event handler #%d\n", 7716 "Routing Event to event handler #%d\n",
7716 ioc->name, cb_idx)); 7717 ioc->name, cb_idx));
7717 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply); 7718 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7718 handlers++; 7719 handlers++;
7719 } 7720 }
7720 } 7721 }
7721 /* FIXME? Examine results here? */ 7722 /* FIXME? Examine results here? */
7722 7723
7723 /* 7724 /*
7724 * If needed, send (a single) EventAck. 7725 * If needed, send (a single) EventAck.
7725 */ 7726 */
7726 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) { 7727 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7727 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7728 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7728 "EventAck required\n",ioc->name)); 7729 "EventAck required\n",ioc->name));
7729 if ((ii = SendEventAck(ioc, pEventReply)) != 0) { 7730 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7730 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n", 7731 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7731 ioc->name, ii)); 7732 ioc->name, ii));
7732 } 7733 }
7733 } 7734 }
7734 7735
7735 *evHandlers = handlers; 7736 *evHandlers = handlers;
7736 return r; 7737 return r;
7737 } 7738 }
7738 7739
7739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7740 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7740 /** 7741 /**
7741 * mpt_fc_log_info - Log information returned from Fibre Channel IOC. 7742 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7742 * @ioc: Pointer to MPT_ADAPTER structure 7743 * @ioc: Pointer to MPT_ADAPTER structure
7743 * @log_info: U32 LogInfo reply word from the IOC 7744 * @log_info: U32 LogInfo reply word from the IOC
7744 * 7745 *
7745 * Refer to lsi/mpi_log_fc.h. 7746 * Refer to lsi/mpi_log_fc.h.
7746 */ 7747 */
7747 static void 7748 static void
7748 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) 7749 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7749 { 7750 {
7750 char *desc = "unknown"; 7751 char *desc = "unknown";
7751 7752
7752 switch (log_info & 0xFF000000) { 7753 switch (log_info & 0xFF000000) {
7753 case MPI_IOCLOGINFO_FC_INIT_BASE: 7754 case MPI_IOCLOGINFO_FC_INIT_BASE:
7754 desc = "FCP Initiator"; 7755 desc = "FCP Initiator";
7755 break; 7756 break;
7756 case MPI_IOCLOGINFO_FC_TARGET_BASE: 7757 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7757 desc = "FCP Target"; 7758 desc = "FCP Target";
7758 break; 7759 break;
7759 case MPI_IOCLOGINFO_FC_LAN_BASE: 7760 case MPI_IOCLOGINFO_FC_LAN_BASE:
7760 desc = "LAN"; 7761 desc = "LAN";
7761 break; 7762 break;
7762 case MPI_IOCLOGINFO_FC_MSG_BASE: 7763 case MPI_IOCLOGINFO_FC_MSG_BASE:
7763 desc = "MPI Message Layer"; 7764 desc = "MPI Message Layer";
7764 break; 7765 break;
7765 case MPI_IOCLOGINFO_FC_LINK_BASE: 7766 case MPI_IOCLOGINFO_FC_LINK_BASE:
7766 desc = "FC Link"; 7767 desc = "FC Link";
7767 break; 7768 break;
7768 case MPI_IOCLOGINFO_FC_CTX_BASE: 7769 case MPI_IOCLOGINFO_FC_CTX_BASE:
7769 desc = "Context Manager"; 7770 desc = "Context Manager";
7770 break; 7771 break;
7771 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET: 7772 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7772 desc = "Invalid Field Offset"; 7773 desc = "Invalid Field Offset";
7773 break; 7774 break;
7774 case MPI_IOCLOGINFO_FC_STATE_CHANGE: 7775 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7775 desc = "State Change Info"; 7776 desc = "State Change Info";
7776 break; 7777 break;
7777 } 7778 }
7778 7779
7779 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n", 7780 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7780 ioc->name, log_info, desc, (log_info & 0xFFFFFF)); 7781 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7781 } 7782 }
7782 7783
7783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7784 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7784 /** 7785 /**
7785 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC. 7786 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7786 * @ioc: Pointer to MPT_ADAPTER structure 7787 * @ioc: Pointer to MPT_ADAPTER structure
7787 * @log_info: U32 LogInfo word from the IOC 7788 * @log_info: U32 LogInfo word from the IOC
7788 * 7789 *
7789 * Refer to lsi/sp_log.h. 7790 * Refer to lsi/sp_log.h.
7790 */ 7791 */
7791 static void 7792 static void
7792 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) 7793 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7793 { 7794 {
7794 u32 info = log_info & 0x00FF0000; 7795 u32 info = log_info & 0x00FF0000;
7795 char *desc = "unknown"; 7796 char *desc = "unknown";
7796 7797
7797 switch (info) { 7798 switch (info) {
7798 case 0x00010000: 7799 case 0x00010000:
7799 desc = "bug! MID not found"; 7800 desc = "bug! MID not found";
7800 break; 7801 break;
7801 7802
7802 case 0x00020000: 7803 case 0x00020000:
7803 desc = "Parity Error"; 7804 desc = "Parity Error";
7804 break; 7805 break;
7805 7806
7806 case 0x00030000: 7807 case 0x00030000:
7807 desc = "ASYNC Outbound Overrun"; 7808 desc = "ASYNC Outbound Overrun";
7808 break; 7809 break;
7809 7810
7810 case 0x00040000: 7811 case 0x00040000:
7811 desc = "SYNC Offset Error"; 7812 desc = "SYNC Offset Error";
7812 break; 7813 break;
7813 7814
7814 case 0x00050000: 7815 case 0x00050000:
7815 desc = "BM Change"; 7816 desc = "BM Change";
7816 break; 7817 break;
7817 7818
7818 case 0x00060000: 7819 case 0x00060000:
7819 desc = "Msg In Overflow"; 7820 desc = "Msg In Overflow";
7820 break; 7821 break;
7821 7822
7822 case 0x00070000: 7823 case 0x00070000:
7823 desc = "DMA Error"; 7824 desc = "DMA Error";
7824 break; 7825 break;
7825 7826
7826 case 0x00080000: 7827 case 0x00080000:
7827 desc = "Outbound DMA Overrun"; 7828 desc = "Outbound DMA Overrun";
7828 break; 7829 break;
7829 7830
7830 case 0x00090000: 7831 case 0x00090000:
7831 desc = "Task Management"; 7832 desc = "Task Management";
7832 break; 7833 break;
7833 7834
7834 case 0x000A0000: 7835 case 0x000A0000:
7835 desc = "Device Problem"; 7836 desc = "Device Problem";
7836 break; 7837 break;
7837 7838
7838 case 0x000B0000: 7839 case 0x000B0000:
7839 desc = "Invalid Phase Change"; 7840 desc = "Invalid Phase Change";
7840 break; 7841 break;
7841 7842
7842 case 0x000C0000: 7843 case 0x000C0000:
7843 desc = "Untagged Table Size"; 7844 desc = "Untagged Table Size";
7844 break; 7845 break;
7845 7846
7846 } 7847 }
7847 7848
7848 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc); 7849 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7849 } 7850 }
7850 7851
7851 /* strings for sas loginfo */ 7852 /* strings for sas loginfo */
7852 static char *originator_str[] = { 7853 static char *originator_str[] = {
7853 "IOP", /* 00h */ 7854 "IOP", /* 00h */
7854 "PL", /* 01h */ 7855 "PL", /* 01h */
7855 "IR" /* 02h */ 7856 "IR" /* 02h */
7856 }; 7857 };
7857 static char *iop_code_str[] = { 7858 static char *iop_code_str[] = {
7858 NULL, /* 00h */ 7859 NULL, /* 00h */
7859 "Invalid SAS Address", /* 01h */ 7860 "Invalid SAS Address", /* 01h */
7860 NULL, /* 02h */ 7861 NULL, /* 02h */
7861 "Invalid Page", /* 03h */ 7862 "Invalid Page", /* 03h */
7862 "Diag Message Error", /* 04h */ 7863 "Diag Message Error", /* 04h */
7863 "Task Terminated", /* 05h */ 7864 "Task Terminated", /* 05h */
7864 "Enclosure Management", /* 06h */ 7865 "Enclosure Management", /* 06h */
7865 "Target Mode" /* 07h */ 7866 "Target Mode" /* 07h */
7866 }; 7867 };
7867 static char *pl_code_str[] = { 7868 static char *pl_code_str[] = {
7868 NULL, /* 00h */ 7869 NULL, /* 00h */
7869 "Open Failure", /* 01h */ 7870 "Open Failure", /* 01h */
7870 "Invalid Scatter Gather List", /* 02h */ 7871 "Invalid Scatter Gather List", /* 02h */
7871 "Wrong Relative Offset or Frame Length", /* 03h */ 7872 "Wrong Relative Offset or Frame Length", /* 03h */
7872 "Frame Transfer Error", /* 04h */ 7873 "Frame Transfer Error", /* 04h */
7873 "Transmit Frame Connected Low", /* 05h */ 7874 "Transmit Frame Connected Low", /* 05h */
7874 "SATA Non-NCQ RW Error Bit Set", /* 06h */ 7875 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7875 "SATA Read Log Receive Data Error", /* 07h */ 7876 "SATA Read Log Receive Data Error", /* 07h */
7876 "SATA NCQ Fail All Commands After Error", /* 08h */ 7877 "SATA NCQ Fail All Commands After Error", /* 08h */
7877 "SATA Error in Receive Set Device Bit FIS", /* 09h */ 7878 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7878 "Receive Frame Invalid Message", /* 0Ah */ 7879 "Receive Frame Invalid Message", /* 0Ah */
7879 "Receive Context Message Valid Error", /* 0Bh */ 7880 "Receive Context Message Valid Error", /* 0Bh */
7880 "Receive Frame Current Frame Error", /* 0Ch */ 7881 "Receive Frame Current Frame Error", /* 0Ch */
7881 "SATA Link Down", /* 0Dh */ 7882 "SATA Link Down", /* 0Dh */
7882 "Discovery SATA Init W IOS", /* 0Eh */ 7883 "Discovery SATA Init W IOS", /* 0Eh */
7883 "Config Invalid Page", /* 0Fh */ 7884 "Config Invalid Page", /* 0Fh */
7884 "Discovery SATA Init Timeout", /* 10h */ 7885 "Discovery SATA Init Timeout", /* 10h */
7885 "Reset", /* 11h */ 7886 "Reset", /* 11h */
7886 "Abort", /* 12h */ 7887 "Abort", /* 12h */
7887 "IO Not Yet Executed", /* 13h */ 7888 "IO Not Yet Executed", /* 13h */
7888 "IO Executed", /* 14h */ 7889 "IO Executed", /* 14h */
7889 "Persistent Reservation Out Not Affiliation " 7890 "Persistent Reservation Out Not Affiliation "
7890 "Owner", /* 15h */ 7891 "Owner", /* 15h */
7891 "Open Transmit DMA Abort", /* 16h */ 7892 "Open Transmit DMA Abort", /* 16h */
7892 "IO Device Missing Delay Retry", /* 17h */ 7893 "IO Device Missing Delay Retry", /* 17h */
7893 "IO Cancelled Due to Recieve Error", /* 18h */ 7894 "IO Cancelled Due to Recieve Error", /* 18h */
7894 NULL, /* 19h */ 7895 NULL, /* 19h */
7895 NULL, /* 1Ah */ 7896 NULL, /* 1Ah */
7896 NULL, /* 1Bh */ 7897 NULL, /* 1Bh */
7897 NULL, /* 1Ch */ 7898 NULL, /* 1Ch */
7898 NULL, /* 1Dh */ 7899 NULL, /* 1Dh */
7899 NULL, /* 1Eh */ 7900 NULL, /* 1Eh */
7900 NULL, /* 1Fh */ 7901 NULL, /* 1Fh */
7901 "Enclosure Management" /* 20h */ 7902 "Enclosure Management" /* 20h */
7902 }; 7903 };
7903 static char *ir_code_str[] = { 7904 static char *ir_code_str[] = {
7904 "Raid Action Error", /* 00h */ 7905 "Raid Action Error", /* 00h */
7905 NULL, /* 00h */ 7906 NULL, /* 00h */
7906 NULL, /* 01h */ 7907 NULL, /* 01h */
7907 NULL, /* 02h */ 7908 NULL, /* 02h */
7908 NULL, /* 03h */ 7909 NULL, /* 03h */
7909 NULL, /* 04h */ 7910 NULL, /* 04h */
7910 NULL, /* 05h */ 7911 NULL, /* 05h */
7911 NULL, /* 06h */ 7912 NULL, /* 06h */
7912 NULL /* 07h */ 7913 NULL /* 07h */
7913 }; 7914 };
7914 static char *raid_sub_code_str[] = { 7915 static char *raid_sub_code_str[] = {
7915 NULL, /* 00h */ 7916 NULL, /* 00h */
7916 "Volume Creation Failed: Data Passed too " 7917 "Volume Creation Failed: Data Passed too "
7917 "Large", /* 01h */ 7918 "Large", /* 01h */
7918 "Volume Creation Failed: Duplicate Volumes " 7919 "Volume Creation Failed: Duplicate Volumes "
7919 "Attempted", /* 02h */ 7920 "Attempted", /* 02h */
7920 "Volume Creation Failed: Max Number " 7921 "Volume Creation Failed: Max Number "
7921 "Supported Volumes Exceeded", /* 03h */ 7922 "Supported Volumes Exceeded", /* 03h */
7922 "Volume Creation Failed: DMA Error", /* 04h */ 7923 "Volume Creation Failed: DMA Error", /* 04h */
7923 "Volume Creation Failed: Invalid Volume Type", /* 05h */ 7924 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7924 "Volume Creation Failed: Error Reading " 7925 "Volume Creation Failed: Error Reading "
7925 "MFG Page 4", /* 06h */ 7926 "MFG Page 4", /* 06h */
7926 "Volume Creation Failed: Creating Internal " 7927 "Volume Creation Failed: Creating Internal "
7927 "Structures", /* 07h */ 7928 "Structures", /* 07h */
7928 NULL, /* 08h */ 7929 NULL, /* 08h */
7929 NULL, /* 09h */ 7930 NULL, /* 09h */
7930 NULL, /* 0Ah */ 7931 NULL, /* 0Ah */
7931 NULL, /* 0Bh */ 7932 NULL, /* 0Bh */
7932 NULL, /* 0Ch */ 7933 NULL, /* 0Ch */
7933 NULL, /* 0Dh */ 7934 NULL, /* 0Dh */
7934 NULL, /* 0Eh */ 7935 NULL, /* 0Eh */
7935 NULL, /* 0Fh */ 7936 NULL, /* 0Fh */
7936 "Activation failed: Already Active Volume", /* 10h */ 7937 "Activation failed: Already Active Volume", /* 10h */
7937 "Activation failed: Unsupported Volume Type", /* 11h */ 7938 "Activation failed: Unsupported Volume Type", /* 11h */
7938 "Activation failed: Too Many Active Volumes", /* 12h */ 7939 "Activation failed: Too Many Active Volumes", /* 12h */
7939 "Activation failed: Volume ID in Use", /* 13h */ 7940 "Activation failed: Volume ID in Use", /* 13h */
7940 "Activation failed: Reported Failure", /* 14h */ 7941 "Activation failed: Reported Failure", /* 14h */
7941 "Activation failed: Importing a Volume", /* 15h */ 7942 "Activation failed: Importing a Volume", /* 15h */
7942 NULL, /* 16h */ 7943 NULL, /* 16h */
7943 NULL, /* 17h */ 7944 NULL, /* 17h */
7944 NULL, /* 18h */ 7945 NULL, /* 18h */
7945 NULL, /* 19h */ 7946 NULL, /* 19h */
7946 NULL, /* 1Ah */ 7947 NULL, /* 1Ah */
7947 NULL, /* 1Bh */ 7948 NULL, /* 1Bh */
7948 NULL, /* 1Ch */ 7949 NULL, /* 1Ch */
7949 NULL, /* 1Dh */ 7950 NULL, /* 1Dh */
7950 NULL, /* 1Eh */ 7951 NULL, /* 1Eh */
7951 NULL, /* 1Fh */ 7952 NULL, /* 1Fh */
7952 "Phys Disk failed: Too Many Phys Disks", /* 20h */ 7953 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7953 "Phys Disk failed: Data Passed too Large", /* 21h */ 7954 "Phys Disk failed: Data Passed too Large", /* 21h */
7954 "Phys Disk failed: DMA Error", /* 22h */ 7955 "Phys Disk failed: DMA Error", /* 22h */
7955 "Phys Disk failed: Invalid <channel:id>", /* 23h */ 7956 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7956 "Phys Disk failed: Creating Phys Disk Config " 7957 "Phys Disk failed: Creating Phys Disk Config "
7957 "Page", /* 24h */ 7958 "Page", /* 24h */
7958 NULL, /* 25h */ 7959 NULL, /* 25h */
7959 NULL, /* 26h */ 7960 NULL, /* 26h */
7960 NULL, /* 27h */ 7961 NULL, /* 27h */
7961 NULL, /* 28h */ 7962 NULL, /* 28h */
7962 NULL, /* 29h */ 7963 NULL, /* 29h */
7963 NULL, /* 2Ah */ 7964 NULL, /* 2Ah */
7964 NULL, /* 2Bh */ 7965 NULL, /* 2Bh */
7965 NULL, /* 2Ch */ 7966 NULL, /* 2Ch */
7966 NULL, /* 2Dh */ 7967 NULL, /* 2Dh */
7967 NULL, /* 2Eh */ 7968 NULL, /* 2Eh */
7968 NULL, /* 2Fh */ 7969 NULL, /* 2Fh */
7969 "Compatibility Error: IR Disabled", /* 30h */ 7970 "Compatibility Error: IR Disabled", /* 30h */
7970 "Compatibility Error: Inquiry Comand Failed", /* 31h */ 7971 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7971 "Compatibility Error: Device not Direct Access " 7972 "Compatibility Error: Device not Direct Access "
7972 "Device ", /* 32h */ 7973 "Device ", /* 32h */
7973 "Compatibility Error: Removable Device Found", /* 33h */ 7974 "Compatibility Error: Removable Device Found", /* 33h */
7974 "Compatibility Error: Device SCSI Version not " 7975 "Compatibility Error: Device SCSI Version not "
7975 "2 or Higher", /* 34h */ 7976 "2 or Higher", /* 34h */
7976 "Compatibility Error: SATA Device, 48 BIT LBA " 7977 "Compatibility Error: SATA Device, 48 BIT LBA "
7977 "not Supported", /* 35h */ 7978 "not Supported", /* 35h */
7978 "Compatibility Error: Device doesn't have " 7979 "Compatibility Error: Device doesn't have "
7979 "512 Byte Block Sizes", /* 36h */ 7980 "512 Byte Block Sizes", /* 36h */
7980 "Compatibility Error: Volume Type Check Failed", /* 37h */ 7981 "Compatibility Error: Volume Type Check Failed", /* 37h */
7981 "Compatibility Error: Volume Type is " 7982 "Compatibility Error: Volume Type is "
7982 "Unsupported by FW", /* 38h */ 7983 "Unsupported by FW", /* 38h */
7983 "Compatibility Error: Disk Drive too Small for " 7984 "Compatibility Error: Disk Drive too Small for "
7984 "use in Volume", /* 39h */ 7985 "use in Volume", /* 39h */
7985 "Compatibility Error: Phys Disk for Create " 7986 "Compatibility Error: Phys Disk for Create "
7986 "Volume not Found", /* 3Ah */ 7987 "Volume not Found", /* 3Ah */
7987 "Compatibility Error: Too Many or too Few " 7988 "Compatibility Error: Too Many or too Few "
7988 "Disks for Volume Type", /* 3Bh */ 7989 "Disks for Volume Type", /* 3Bh */
7989 "Compatibility Error: Disk stripe Sizes " 7990 "Compatibility Error: Disk stripe Sizes "
7990 "Must be 64KB", /* 3Ch */ 7991 "Must be 64KB", /* 3Ch */
7991 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */ 7992 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7992 }; 7993 };
7993 7994
7994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7995 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7995 /** 7996 /**
7996 * mpt_sas_log_info - Log information returned from SAS IOC. 7997 * mpt_sas_log_info - Log information returned from SAS IOC.
7997 * @ioc: Pointer to MPT_ADAPTER structure 7998 * @ioc: Pointer to MPT_ADAPTER structure
7998 * @log_info: U32 LogInfo reply word from the IOC 7999 * @log_info: U32 LogInfo reply word from the IOC
7999 * 8000 *
8000 * Refer to lsi/mpi_log_sas.h. 8001 * Refer to lsi/mpi_log_sas.h.
8001 **/ 8002 **/
8002 static void 8003 static void
8003 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) 8004 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
8004 { 8005 {
8005 union loginfo_type { 8006 union loginfo_type {
8006 u32 loginfo; 8007 u32 loginfo;
8007 struct { 8008 struct {
8008 u32 subcode:16; 8009 u32 subcode:16;
8009 u32 code:8; 8010 u32 code:8;
8010 u32 originator:4; 8011 u32 originator:4;
8011 u32 bus_type:4; 8012 u32 bus_type:4;
8012 }dw; 8013 }dw;
8013 }; 8014 };
8014 union loginfo_type sas_loginfo; 8015 union loginfo_type sas_loginfo;
8015 char *originator_desc = NULL; 8016 char *originator_desc = NULL;
8016 char *code_desc = NULL; 8017 char *code_desc = NULL;
8017 char *sub_code_desc = NULL; 8018 char *sub_code_desc = NULL;
8018 8019
8019 sas_loginfo.loginfo = log_info; 8020 sas_loginfo.loginfo = log_info;
8020 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) && 8021 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8021 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str))) 8022 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8022 return; 8023 return;
8023 8024
8024 originator_desc = originator_str[sas_loginfo.dw.originator]; 8025 originator_desc = originator_str[sas_loginfo.dw.originator];
8025 8026
8026 switch (sas_loginfo.dw.originator) { 8027 switch (sas_loginfo.dw.originator) {
8027 8028
8028 case 0: /* IOP */ 8029 case 0: /* IOP */
8029 if (sas_loginfo.dw.code < 8030 if (sas_loginfo.dw.code <
8030 ARRAY_SIZE(iop_code_str)) 8031 ARRAY_SIZE(iop_code_str))
8031 code_desc = iop_code_str[sas_loginfo.dw.code]; 8032 code_desc = iop_code_str[sas_loginfo.dw.code];
8032 break; 8033 break;
8033 case 1: /* PL */ 8034 case 1: /* PL */
8034 if (sas_loginfo.dw.code < 8035 if (sas_loginfo.dw.code <
8035 ARRAY_SIZE(pl_code_str)) 8036 ARRAY_SIZE(pl_code_str))
8036 code_desc = pl_code_str[sas_loginfo.dw.code]; 8037 code_desc = pl_code_str[sas_loginfo.dw.code];
8037 break; 8038 break;
8038 case 2: /* IR */ 8039 case 2: /* IR */
8039 if (sas_loginfo.dw.code >= 8040 if (sas_loginfo.dw.code >=
8040 ARRAY_SIZE(ir_code_str)) 8041 ARRAY_SIZE(ir_code_str))
8041 break; 8042 break;
8042 code_desc = ir_code_str[sas_loginfo.dw.code]; 8043 code_desc = ir_code_str[sas_loginfo.dw.code];
8043 if (sas_loginfo.dw.subcode >= 8044 if (sas_loginfo.dw.subcode >=
8044 ARRAY_SIZE(raid_sub_code_str)) 8045 ARRAY_SIZE(raid_sub_code_str))
8045 break; 8046 break;
8046 if (sas_loginfo.dw.code == 0) 8047 if (sas_loginfo.dw.code == 0)
8047 sub_code_desc = 8048 sub_code_desc =
8048 raid_sub_code_str[sas_loginfo.dw.subcode]; 8049 raid_sub_code_str[sas_loginfo.dw.subcode];
8049 break; 8050 break;
8050 default: 8051 default:
8051 return; 8052 return;
8052 } 8053 }
8053 8054
8054 if (sub_code_desc != NULL) 8055 if (sub_code_desc != NULL)
8055 printk(MYIOC_s_INFO_FMT 8056 printk(MYIOC_s_INFO_FMT
8056 "LogInfo(0x%08x): Originator={%s}, Code={%s}," 8057 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8057 " SubCode={%s}\n", 8058 " SubCode={%s}\n",
8058 ioc->name, log_info, originator_desc, code_desc, 8059 ioc->name, log_info, originator_desc, code_desc,
8059 sub_code_desc); 8060 sub_code_desc);
8060 else if (code_desc != NULL) 8061 else if (code_desc != NULL)
8061 printk(MYIOC_s_INFO_FMT 8062 printk(MYIOC_s_INFO_FMT
8062 "LogInfo(0x%08x): Originator={%s}, Code={%s}," 8063 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8063 " SubCode(0x%04x)\n", 8064 " SubCode(0x%04x)\n",
8064 ioc->name, log_info, originator_desc, code_desc, 8065 ioc->name, log_info, originator_desc, code_desc,
8065 sas_loginfo.dw.subcode); 8066 sas_loginfo.dw.subcode);
8066 else 8067 else
8067 printk(MYIOC_s_INFO_FMT 8068 printk(MYIOC_s_INFO_FMT
8068 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x)," 8069 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8069 " SubCode(0x%04x)\n", 8070 " SubCode(0x%04x)\n",
8070 ioc->name, log_info, originator_desc, 8071 ioc->name, log_info, originator_desc,
8071 sas_loginfo.dw.code, sas_loginfo.dw.subcode); 8072 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
8072 } 8073 }
8073 8074
8074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 8075 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8075 /** 8076 /**
8076 * mpt_iocstatus_info_config - IOCSTATUS information for config pages 8077 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8077 * @ioc: Pointer to MPT_ADAPTER structure 8078 * @ioc: Pointer to MPT_ADAPTER structure
8078 * @ioc_status: U32 IOCStatus word from IOC 8079 * @ioc_status: U32 IOCStatus word from IOC
8079 * @mf: Pointer to MPT request frame 8080 * @mf: Pointer to MPT request frame
8080 * 8081 *
8081 * Refer to lsi/mpi.h. 8082 * Refer to lsi/mpi.h.
8082 **/ 8083 **/
8083 static void 8084 static void
8084 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) 8085 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8085 { 8086 {
8086 Config_t *pReq = (Config_t *)mf; 8087 Config_t *pReq = (Config_t *)mf;
8087 char extend_desc[EVENT_DESCR_STR_SZ]; 8088 char extend_desc[EVENT_DESCR_STR_SZ];
8088 char *desc = NULL; 8089 char *desc = NULL;
8089 u32 form; 8090 u32 form;
8090 u8 page_type; 8091 u8 page_type;
8091 8092
8092 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED) 8093 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8093 page_type = pReq->ExtPageType; 8094 page_type = pReq->ExtPageType;
8094 else 8095 else
8095 page_type = pReq->Header.PageType; 8096 page_type = pReq->Header.PageType;
8096 8097
8097 /* 8098 /*
8098 * ignore invalid page messages for GET_NEXT_HANDLE 8099 * ignore invalid page messages for GET_NEXT_HANDLE
8099 */ 8100 */
8100 form = le32_to_cpu(pReq->PageAddress); 8101 form = le32_to_cpu(pReq->PageAddress);
8101 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) { 8102 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8102 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE || 8103 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8103 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER || 8104 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8104 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) { 8105 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8105 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) == 8106 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8106 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) 8107 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8107 return; 8108 return;
8108 } 8109 }
8109 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE) 8110 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8110 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) == 8111 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8111 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID) 8112 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8112 return; 8113 return;
8113 } 8114 }
8114 8115
8115 snprintf(extend_desc, EVENT_DESCR_STR_SZ, 8116 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8116 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh", 8117 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8117 page_type, pReq->Header.PageNumber, pReq->Action, form); 8118 page_type, pReq->Header.PageNumber, pReq->Action, form);
8118 8119
8119 switch (ioc_status) { 8120 switch (ioc_status) {
8120 8121
8121 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ 8122 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8122 desc = "Config Page Invalid Action"; 8123 desc = "Config Page Invalid Action";
8123 break; 8124 break;
8124 8125
8125 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ 8126 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8126 desc = "Config Page Invalid Type"; 8127 desc = "Config Page Invalid Type";
8127 break; 8128 break;
8128 8129
8129 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ 8130 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8130 desc = "Config Page Invalid Page"; 8131 desc = "Config Page Invalid Page";
8131 break; 8132 break;
8132 8133
8133 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ 8134 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8134 desc = "Config Page Invalid Data"; 8135 desc = "Config Page Invalid Data";
8135 break; 8136 break;
8136 8137
8137 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ 8138 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8138 desc = "Config Page No Defaults"; 8139 desc = "Config Page No Defaults";
8139 break; 8140 break;
8140 8141
8141 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ 8142 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8142 desc = "Config Page Can't Commit"; 8143 desc = "Config Page Can't Commit";
8143 break; 8144 break;
8144 } 8145 }
8145 8146
8146 if (!desc) 8147 if (!desc)
8147 return; 8148 return;
8148 8149
8149 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n", 8150 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8150 ioc->name, ioc_status, desc, extend_desc)); 8151 ioc->name, ioc_status, desc, extend_desc));
8151 } 8152 }
8152 8153
8153 /** 8154 /**
8154 * mpt_iocstatus_info - IOCSTATUS information returned from IOC. 8155 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8155 * @ioc: Pointer to MPT_ADAPTER structure 8156 * @ioc: Pointer to MPT_ADAPTER structure
8156 * @ioc_status: U32 IOCStatus word from IOC 8157 * @ioc_status: U32 IOCStatus word from IOC
8157 * @mf: Pointer to MPT request frame 8158 * @mf: Pointer to MPT request frame
8158 * 8159 *
8159 * Refer to lsi/mpi.h. 8160 * Refer to lsi/mpi.h.
8160 **/ 8161 **/
8161 static void 8162 static void
8162 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) 8163 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8163 { 8164 {
8164 u32 status = ioc_status & MPI_IOCSTATUS_MASK; 8165 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8165 char *desc = NULL; 8166 char *desc = NULL;
8166 8167
8167 switch (status) { 8168 switch (status) {
8168 8169
8169 /****************************************************************************/ 8170 /****************************************************************************/
8170 /* Common IOCStatus values for all replies */ 8171 /* Common IOCStatus values for all replies */
8171 /****************************************************************************/ 8172 /****************************************************************************/
8172 8173
8173 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ 8174 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8174 desc = "Invalid Function"; 8175 desc = "Invalid Function";
8175 break; 8176 break;
8176 8177
8177 case MPI_IOCSTATUS_BUSY: /* 0x0002 */ 8178 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8178 desc = "Busy"; 8179 desc = "Busy";
8179 break; 8180 break;
8180 8181
8181 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */ 8182 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8182 desc = "Invalid SGL"; 8183 desc = "Invalid SGL";
8183 break; 8184 break;
8184 8185
8185 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */ 8186 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8186 desc = "Internal Error"; 8187 desc = "Internal Error";
8187 break; 8188 break;
8188 8189
8189 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */ 8190 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8190 desc = "Reserved"; 8191 desc = "Reserved";
8191 break; 8192 break;
8192 8193
8193 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */ 8194 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8194 desc = "Insufficient Resources"; 8195 desc = "Insufficient Resources";
8195 break; 8196 break;
8196 8197
8197 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */ 8198 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8198 desc = "Invalid Field"; 8199 desc = "Invalid Field";
8199 break; 8200 break;
8200 8201
8201 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ 8202 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8202 desc = "Invalid State"; 8203 desc = "Invalid State";
8203 break; 8204 break;
8204 8205
8205 /****************************************************************************/ 8206 /****************************************************************************/
8206 /* Config IOCStatus values */ 8207 /* Config IOCStatus values */
8207 /****************************************************************************/ 8208 /****************************************************************************/
8208 8209
8209 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ 8210 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8210 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ 8211 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8211 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ 8212 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8212 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ 8213 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8213 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ 8214 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8214 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ 8215 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8215 mpt_iocstatus_info_config(ioc, status, mf); 8216 mpt_iocstatus_info_config(ioc, status, mf);
8216 break; 8217 break;
8217 8218
8218 /****************************************************************************/ 8219 /****************************************************************************/
8219 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */ 8220 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8220 /* */ 8221 /* */
8221 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */ 8222 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8222 /* */ 8223 /* */
8223 /****************************************************************************/ 8224 /****************************************************************************/
8224 8225
8225 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 8226 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8226 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 8227 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8227 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ 8228 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8228 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ 8229 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8229 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ 8230 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8230 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ 8231 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8231 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ 8232 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8232 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ 8233 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8233 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ 8234 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8234 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 8235 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8235 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ 8236 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8236 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ 8237 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8237 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ 8238 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8238 break; 8239 break;
8239 8240
8240 /****************************************************************************/ 8241 /****************************************************************************/
8241 /* SCSI Target values */ 8242 /* SCSI Target values */
8242 /****************************************************************************/ 8243 /****************************************************************************/
8243 8244
8244 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */ 8245 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8245 desc = "Target: Priority IO"; 8246 desc = "Target: Priority IO";
8246 break; 8247 break;
8247 8248
8248 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */ 8249 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8249 desc = "Target: Invalid Port"; 8250 desc = "Target: Invalid Port";
8250 break; 8251 break;
8251 8252
8252 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */ 8253 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8253 desc = "Target Invalid IO Index:"; 8254 desc = "Target Invalid IO Index:";
8254 break; 8255 break;
8255 8256
8256 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */ 8257 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8257 desc = "Target: Aborted"; 8258 desc = "Target: Aborted";
8258 break; 8259 break;
8259 8260
8260 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */ 8261 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8261 desc = "Target: No Conn Retryable"; 8262 desc = "Target: No Conn Retryable";
8262 break; 8263 break;
8263 8264
8264 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */ 8265 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8265 desc = "Target: No Connection"; 8266 desc = "Target: No Connection";
8266 break; 8267 break;
8267 8268
8268 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */ 8269 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8269 desc = "Target: Transfer Count Mismatch"; 8270 desc = "Target: Transfer Count Mismatch";
8270 break; 8271 break;
8271 8272
8272 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */ 8273 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8273 desc = "Target: STS Data not Sent"; 8274 desc = "Target: STS Data not Sent";
8274 break; 8275 break;
8275 8276
8276 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */ 8277 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8277 desc = "Target: Data Offset Error"; 8278 desc = "Target: Data Offset Error";
8278 break; 8279 break;
8279 8280
8280 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */ 8281 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8281 desc = "Target: Too Much Write Data"; 8282 desc = "Target: Too Much Write Data";
8282 break; 8283 break;
8283 8284
8284 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */ 8285 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8285 desc = "Target: IU Too Short"; 8286 desc = "Target: IU Too Short";
8286 break; 8287 break;
8287 8288
8288 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */ 8289 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8289 desc = "Target: ACK NAK Timeout"; 8290 desc = "Target: ACK NAK Timeout";
8290 break; 8291 break;
8291 8292
8292 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */ 8293 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8293 desc = "Target: Nak Received"; 8294 desc = "Target: Nak Received";
8294 break; 8295 break;
8295 8296
8296 /****************************************************************************/ 8297 /****************************************************************************/
8297 /* Fibre Channel Direct Access values */ 8298 /* Fibre Channel Direct Access values */
8298 /****************************************************************************/ 8299 /****************************************************************************/
8299 8300
8300 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */ 8301 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8301 desc = "FC: Aborted"; 8302 desc = "FC: Aborted";
8302 break; 8303 break;
8303 8304
8304 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */ 8305 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8305 desc = "FC: RX ID Invalid"; 8306 desc = "FC: RX ID Invalid";
8306 break; 8307 break;
8307 8308
8308 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */ 8309 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8309 desc = "FC: DID Invalid"; 8310 desc = "FC: DID Invalid";
8310 break; 8311 break;
8311 8312
8312 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */ 8313 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8313 desc = "FC: Node Logged Out"; 8314 desc = "FC: Node Logged Out";
8314 break; 8315 break;
8315 8316
8316 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */ 8317 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8317 desc = "FC: Exchange Canceled"; 8318 desc = "FC: Exchange Canceled";
8318 break; 8319 break;
8319 8320
8320 /****************************************************************************/ 8321 /****************************************************************************/
8321 /* LAN values */ 8322 /* LAN values */
8322 /****************************************************************************/ 8323 /****************************************************************************/
8323 8324
8324 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */ 8325 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8325 desc = "LAN: Device not Found"; 8326 desc = "LAN: Device not Found";
8326 break; 8327 break;
8327 8328
8328 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */ 8329 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8329 desc = "LAN: Device Failure"; 8330 desc = "LAN: Device Failure";
8330 break; 8331 break;
8331 8332
8332 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */ 8333 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8333 desc = "LAN: Transmit Error"; 8334 desc = "LAN: Transmit Error";
8334 break; 8335 break;
8335 8336
8336 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */ 8337 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8337 desc = "LAN: Transmit Aborted"; 8338 desc = "LAN: Transmit Aborted";
8338 break; 8339 break;
8339 8340
8340 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */ 8341 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8341 desc = "LAN: Receive Error"; 8342 desc = "LAN: Receive Error";
8342 break; 8343 break;
8343 8344
8344 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */ 8345 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8345 desc = "LAN: Receive Aborted"; 8346 desc = "LAN: Receive Aborted";
8346 break; 8347 break;
8347 8348
8348 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */ 8349 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8349 desc = "LAN: Partial Packet"; 8350 desc = "LAN: Partial Packet";
8350 break; 8351 break;
8351 8352
8352 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */ 8353 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8353 desc = "LAN: Canceled"; 8354 desc = "LAN: Canceled";
8354 break; 8355 break;
8355 8356
8356 /****************************************************************************/ 8357 /****************************************************************************/
8357 /* Serial Attached SCSI values */ 8358 /* Serial Attached SCSI values */
8358 /****************************************************************************/ 8359 /****************************************************************************/
8359 8360
8360 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */ 8361 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8361 desc = "SAS: SMP Request Failed"; 8362 desc = "SAS: SMP Request Failed";
8362 break; 8363 break;
8363 8364
8364 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */ 8365 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8365 desc = "SAS: SMP Data Overrun"; 8366 desc = "SAS: SMP Data Overrun";
8366 break; 8367 break;
8367 8368
8368 default: 8369 default:
8369 desc = "Others"; 8370 desc = "Others";
8370 break; 8371 break;
8371 } 8372 }
8372 8373
8373 if (!desc) 8374 if (!desc)
8374 return; 8375 return;
8375 8376
8376 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n", 8377 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8377 ioc->name, status, desc)); 8378 ioc->name, status, desc));
8378 } 8379 }
8379 8380
8380 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 8381 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8381 EXPORT_SYMBOL(mpt_attach); 8382 EXPORT_SYMBOL(mpt_attach);
8382 EXPORT_SYMBOL(mpt_detach); 8383 EXPORT_SYMBOL(mpt_detach);
8383 #ifdef CONFIG_PM 8384 #ifdef CONFIG_PM
8384 EXPORT_SYMBOL(mpt_resume); 8385 EXPORT_SYMBOL(mpt_resume);
8385 EXPORT_SYMBOL(mpt_suspend); 8386 EXPORT_SYMBOL(mpt_suspend);
8386 #endif 8387 #endif
8387 EXPORT_SYMBOL(ioc_list); 8388 EXPORT_SYMBOL(ioc_list);
8388 EXPORT_SYMBOL(mpt_register); 8389 EXPORT_SYMBOL(mpt_register);
8389 EXPORT_SYMBOL(mpt_deregister); 8390 EXPORT_SYMBOL(mpt_deregister);
8390 EXPORT_SYMBOL(mpt_event_register); 8391 EXPORT_SYMBOL(mpt_event_register);
8391 EXPORT_SYMBOL(mpt_event_deregister); 8392 EXPORT_SYMBOL(mpt_event_deregister);
8392 EXPORT_SYMBOL(mpt_reset_register); 8393 EXPORT_SYMBOL(mpt_reset_register);
8393 EXPORT_SYMBOL(mpt_reset_deregister); 8394 EXPORT_SYMBOL(mpt_reset_deregister);
8394 EXPORT_SYMBOL(mpt_device_driver_register); 8395 EXPORT_SYMBOL(mpt_device_driver_register);
8395 EXPORT_SYMBOL(mpt_device_driver_deregister); 8396 EXPORT_SYMBOL(mpt_device_driver_deregister);
8396 EXPORT_SYMBOL(mpt_get_msg_frame); 8397 EXPORT_SYMBOL(mpt_get_msg_frame);
8397 EXPORT_SYMBOL(mpt_put_msg_frame); 8398 EXPORT_SYMBOL(mpt_put_msg_frame);
8398 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri); 8399 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8399 EXPORT_SYMBOL(mpt_free_msg_frame); 8400 EXPORT_SYMBOL(mpt_free_msg_frame);
8400 EXPORT_SYMBOL(mpt_send_handshake_request); 8401 EXPORT_SYMBOL(mpt_send_handshake_request);
8401 EXPORT_SYMBOL(mpt_verify_adapter); 8402 EXPORT_SYMBOL(mpt_verify_adapter);
8402 EXPORT_SYMBOL(mpt_GetIocState); 8403 EXPORT_SYMBOL(mpt_GetIocState);
8403 EXPORT_SYMBOL(mpt_print_ioc_summary); 8404 EXPORT_SYMBOL(mpt_print_ioc_summary);
8404 EXPORT_SYMBOL(mpt_HardResetHandler); 8405 EXPORT_SYMBOL(mpt_HardResetHandler);
8405 EXPORT_SYMBOL(mpt_config); 8406 EXPORT_SYMBOL(mpt_config);
8406 EXPORT_SYMBOL(mpt_findImVolumes); 8407 EXPORT_SYMBOL(mpt_findImVolumes);
8407 EXPORT_SYMBOL(mpt_alloc_fw_memory); 8408 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8408 EXPORT_SYMBOL(mpt_free_fw_memory); 8409 EXPORT_SYMBOL(mpt_free_fw_memory);
8409 EXPORT_SYMBOL(mptbase_sas_persist_operation); 8410 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8410 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0); 8411 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8411 8412
8412 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 8413 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8413 /** 8414 /**
8414 * fusion_init - Fusion MPT base driver initialization routine. 8415 * fusion_init - Fusion MPT base driver initialization routine.
8415 * 8416 *
8416 * Returns 0 for success, non-zero for failure. 8417 * Returns 0 for success, non-zero for failure.
8417 */ 8418 */
8418 static int __init 8419 static int __init
8419 fusion_init(void) 8420 fusion_init(void)
8420 { 8421 {
8421 u8 cb_idx; 8422 u8 cb_idx;
8422 8423
8423 show_mptmod_ver(my_NAME, my_VERSION); 8424 show_mptmod_ver(my_NAME, my_VERSION);
8424 printk(KERN_INFO COPYRIGHT "\n"); 8425 printk(KERN_INFO COPYRIGHT "\n");
8425 8426
8426 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 8427 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8427 MptCallbacks[cb_idx] = NULL; 8428 MptCallbacks[cb_idx] = NULL;
8428 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; 8429 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8429 MptEvHandlers[cb_idx] = NULL; 8430 MptEvHandlers[cb_idx] = NULL;
8430 MptResetHandlers[cb_idx] = NULL; 8431 MptResetHandlers[cb_idx] = NULL;
8431 } 8432 }
8432 8433
8433 /* Register ourselves (mptbase) in order to facilitate 8434 /* Register ourselves (mptbase) in order to facilitate
8434 * EventNotification handling. 8435 * EventNotification handling.
8435 */ 8436 */
8436 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER); 8437 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
8437 8438
8438 /* Register for hard reset handling callbacks. 8439 /* Register for hard reset handling callbacks.
8439 */ 8440 */
8440 mpt_reset_register(mpt_base_index, mpt_ioc_reset); 8441 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8441 8442
8442 #ifdef CONFIG_PROC_FS 8443 #ifdef CONFIG_PROC_FS
8443 (void) procmpt_create(); 8444 (void) procmpt_create();
8444 #endif 8445 #endif
8445 return 0; 8446 return 0;
8446 } 8447 }
8447 8448
8448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 8449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8449 /** 8450 /**
8450 * fusion_exit - Perform driver unload cleanup. 8451 * fusion_exit - Perform driver unload cleanup.
8451 * 8452 *
8452 * This routine frees all resources associated with each MPT adapter 8453 * This routine frees all resources associated with each MPT adapter
8453 * and removes all %MPT_PROCFS_MPTBASEDIR entries. 8454 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8454 */ 8455 */
8455 static void __exit 8456 static void __exit
8456 fusion_exit(void) 8457 fusion_exit(void)
8457 { 8458 {
8458 8459
8459 mpt_reset_deregister(mpt_base_index); 8460 mpt_reset_deregister(mpt_base_index);
8460 8461
8461 #ifdef CONFIG_PROC_FS 8462 #ifdef CONFIG_PROC_FS
8462 procmpt_destroy(); 8463 procmpt_destroy();
8463 #endif 8464 #endif
8464 } 8465 }
8465 8466
8466 module_init(fusion_init); 8467 module_init(fusion_init);
8467 module_exit(fusion_exit); 8468 module_exit(fusion_exit);
8468 8469