]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/message/fusion/mptbase.c
Merge commit 'v2.6.26' into bkl-removal
[mirror_ubuntu-zesty-kernel.git] / drivers / message / fusion / mptbase.c
1 /*
2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
7 *
8 * Copyright (c) 1999-2007 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
10 *
11 */
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
13 /*
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
16 the Free Software Foundation; version 2 of the License.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 NO WARRANTY
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
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,
32 programs or equipment, and unavailability or interruption of operations.
33
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
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
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
42
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
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
46 */
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
61 #include <asm/io.h>
62 #ifdef CONFIG_MTRR
63 #include <asm/mtrr.h>
64 #endif
65
66 #include "mptbase.h"
67 #include "lsi/mpi_log_fc.h"
68
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
73
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
78
79 /*
80 * cmd line parameters
81 */
82 static int mpt_msi_enable = -1;
83 module_param(mpt_msi_enable, int, 0);
84 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
85
86 static int mpt_channel_mapping;
87 module_param(mpt_channel_mapping, int, 0);
88 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
89
90 static int mpt_debug_level;
91 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
92 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
93 &mpt_debug_level, 0600);
94 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
95
96 #ifdef MFCNT
97 static int mfcounter = 0;
98 #define PRINT_MF_COUNT 20000
99 #endif
100
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
102 /*
103 * Public data...
104 */
105
106 struct proc_dir_entry *mpt_proc_root_dir;
107
108 #define WHOINIT_UNKNOWN 0xAA
109
110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
111 /*
112 * Private data...
113 */
114 /* Adapter link list */
115 LIST_HEAD(ioc_list);
116 /* Callback lookup table */
117 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
118 /* Protocol driver class lookup table */
119 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
120 /* Event handler lookup table */
121 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
122 /* Reset handler lookup table */
123 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
124 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
125
126 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
127
128 /*
129 * Driver Callback Index's
130 */
131 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
132 static u8 last_drv_idx;
133
134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
135 /*
136 * Forward protos...
137 */
138 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
139 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
140 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
141 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
142 int sleepFlag);
143 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
144 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
145 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
146 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
147
148 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
149 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
150 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
151 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
152 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
153 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
154 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
155 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
156 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
157 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
158 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
159 static int PrimeIocFifos(MPT_ADAPTER *ioc);
160 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
161 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
162 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
163 static int GetLanConfigPages(MPT_ADAPTER *ioc);
164 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
165 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
166 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
167 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
168 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
169 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
170 static void mpt_timer_expired(unsigned long data);
171 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
172 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
173 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
174 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
175 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
176
177 #ifdef CONFIG_PROC_FS
178 static int procmpt_summary_read(char *buf, char **start, off_t offset,
179 int request, int *eof, void *data);
180 static int procmpt_version_read(char *buf, char **start, off_t offset,
181 int request, int *eof, void *data);
182 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
183 int request, int *eof, void *data);
184 #endif
185 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
186
187 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
188 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
189 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
190 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
191 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
192 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
193 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
194 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
195
196 /* module entry point */
197 static int __init fusion_init (void);
198 static void __exit fusion_exit (void);
199
200 #define CHIPREG_READ32(addr) readl_relaxed(addr)
201 #define CHIPREG_READ32_dmasync(addr) readl(addr)
202 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
203 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
204 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
205
206 static void
207 pci_disable_io_access(struct pci_dev *pdev)
208 {
209 u16 command_reg;
210
211 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
212 command_reg &= ~1;
213 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
214 }
215
216 static void
217 pci_enable_io_access(struct pci_dev *pdev)
218 {
219 u16 command_reg;
220
221 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
222 command_reg |= 1;
223 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
224 }
225
226 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
227 {
228 int ret = param_set_int(val, kp);
229 MPT_ADAPTER *ioc;
230
231 if (ret)
232 return ret;
233
234 list_for_each_entry(ioc, &ioc_list, list)
235 ioc->debug_level = mpt_debug_level;
236 return 0;
237 }
238
239 /**
240 * mpt_get_cb_idx - obtain cb_idx for registered driver
241 * @dclass: class driver enum
242 *
243 * Returns cb_idx, or zero means it wasn't found
244 **/
245 static u8
246 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
247 {
248 u8 cb_idx;
249
250 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
251 if (MptDriverClass[cb_idx] == dclass)
252 return cb_idx;
253 return 0;
254 }
255
256 /*
257 * Process turbo (context) reply...
258 */
259 static void
260 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
261 {
262 MPT_FRAME_HDR *mf = NULL;
263 MPT_FRAME_HDR *mr = NULL;
264 u16 req_idx = 0;
265 u8 cb_idx;
266
267 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
268 ioc->name, pa));
269
270 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
271 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
272 req_idx = pa & 0x0000FFFF;
273 cb_idx = (pa & 0x00FF0000) >> 16;
274 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
275 break;
276 case MPI_CONTEXT_REPLY_TYPE_LAN:
277 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
278 /*
279 * Blind set of mf to NULL here was fatal
280 * after lan_reply says "freeme"
281 * Fix sort of combined with an optimization here;
282 * added explicit check for case where lan_reply
283 * was just returning 1 and doing nothing else.
284 * For this case skip the callback, but set up
285 * proper mf value first here:-)
286 */
287 if ((pa & 0x58000000) == 0x58000000) {
288 req_idx = pa & 0x0000FFFF;
289 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
290 mpt_free_msg_frame(ioc, mf);
291 mb();
292 return;
293 break;
294 }
295 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
296 break;
297 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
298 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
299 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
300 break;
301 default:
302 cb_idx = 0;
303 BUG();
304 }
305
306 /* Check for (valid) IO callback! */
307 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
308 MptCallbacks[cb_idx] == NULL) {
309 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
310 __FUNCTION__, ioc->name, cb_idx);
311 goto out;
312 }
313
314 if (MptCallbacks[cb_idx](ioc, mf, mr))
315 mpt_free_msg_frame(ioc, mf);
316 out:
317 mb();
318 }
319
320 static void
321 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
322 {
323 MPT_FRAME_HDR *mf;
324 MPT_FRAME_HDR *mr;
325 u16 req_idx;
326 u8 cb_idx;
327 int freeme;
328
329 u32 reply_dma_low;
330 u16 ioc_stat;
331
332 /* non-TURBO reply! Hmmm, something may be up...
333 * Newest turbo reply mechanism; get address
334 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
335 */
336
337 /* Map DMA address of reply header to cpu address.
338 * pa is 32 bits - but the dma address may be 32 or 64 bits
339 * get offset based only only the low addresses
340 */
341
342 reply_dma_low = (pa <<= 1);
343 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
344 (reply_dma_low - ioc->reply_frames_low_dma));
345
346 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
347 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
348 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
349
350 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
351 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
352 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
353
354 /* Check/log IOC log info
355 */
356 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
357 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
358 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
359 if (ioc->bus_type == FC)
360 mpt_fc_log_info(ioc, log_info);
361 else if (ioc->bus_type == SPI)
362 mpt_spi_log_info(ioc, log_info);
363 else if (ioc->bus_type == SAS)
364 mpt_sas_log_info(ioc, log_info);
365 }
366
367 if (ioc_stat & MPI_IOCSTATUS_MASK)
368 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
369
370 /* Check for (valid) IO callback! */
371 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
372 MptCallbacks[cb_idx] == NULL) {
373 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
374 __FUNCTION__, ioc->name, cb_idx);
375 freeme = 0;
376 goto out;
377 }
378
379 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
380
381 out:
382 /* Flush (non-TURBO) reply with a WRITE! */
383 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
384
385 if (freeme)
386 mpt_free_msg_frame(ioc, mf);
387 mb();
388 }
389
390 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
391 /**
392 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
393 * @irq: irq number (not used)
394 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
395 *
396 * This routine is registered via the request_irq() kernel API call,
397 * and handles all interrupts generated from a specific MPT adapter
398 * (also referred to as a IO Controller or IOC).
399 * This routine must clear the interrupt from the adapter and does
400 * so by reading the reply FIFO. Multiple replies may be processed
401 * per single call to this routine.
402 *
403 * This routine handles register-level access of the adapter but
404 * dispatches (calls) a protocol-specific callback routine to handle
405 * the protocol-specific details of the MPT request completion.
406 */
407 static irqreturn_t
408 mpt_interrupt(int irq, void *bus_id)
409 {
410 MPT_ADAPTER *ioc = bus_id;
411 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
412
413 if (pa == 0xFFFFFFFF)
414 return IRQ_NONE;
415
416 /*
417 * Drain the reply FIFO!
418 */
419 do {
420 if (pa & MPI_ADDRESS_REPLY_A_BIT)
421 mpt_reply(ioc, pa);
422 else
423 mpt_turbo_reply(ioc, pa);
424 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
425 } while (pa != 0xFFFFFFFF);
426
427 return IRQ_HANDLED;
428 }
429
430 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
431 /**
432 * mpt_base_reply - MPT base driver's callback routine
433 * @ioc: Pointer to MPT_ADAPTER structure
434 * @mf: Pointer to original MPT request frame
435 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
436 *
437 * MPT base driver's callback routine; all base driver
438 * "internal" request/reply processing is routed here.
439 * Currently used for EventNotification and EventAck handling.
440 *
441 * Returns 1 indicating original alloc'd request frame ptr
442 * should be freed, or 0 if it shouldn't.
443 */
444 static int
445 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
446 {
447 int freereq = 1;
448 u8 func;
449
450 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
451 #ifdef CONFIG_FUSION_LOGGING
452 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
453 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
454 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
455 ioc->name, mf));
456 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
457 }
458 #endif
459
460 func = reply->u.hdr.Function;
461 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
462 ioc->name, func));
463
464 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
465 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
466 int evHandlers = 0;
467 int results;
468
469 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
470 if (results != evHandlers) {
471 /* CHECKME! Any special handling needed here? */
472 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
473 ioc->name, evHandlers, results));
474 }
475
476 /*
477 * Hmmm... It seems that EventNotificationReply is an exception
478 * to the rule of one reply per request.
479 */
480 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
481 freereq = 0;
482 } else {
483 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
484 ioc->name, pEvReply));
485 }
486
487 #ifdef CONFIG_PROC_FS
488 // LogEvent(ioc, pEvReply);
489 #endif
490
491 } else if (func == MPI_FUNCTION_EVENT_ACK) {
492 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
493 ioc->name));
494 } else if (func == MPI_FUNCTION_CONFIG) {
495 CONFIGPARMS *pCfg;
496 unsigned long flags;
497
498 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
499 ioc->name, mf, reply));
500
501 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
502
503 if (pCfg) {
504 /* disable timer and remove from linked list */
505 del_timer(&pCfg->timer);
506
507 spin_lock_irqsave(&ioc->FreeQlock, flags);
508 list_del(&pCfg->linkage);
509 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
510
511 /*
512 * If IOC Status is SUCCESS, save the header
513 * and set the status code to GOOD.
514 */
515 pCfg->status = MPT_CONFIG_ERROR;
516 if (reply) {
517 ConfigReply_t *pReply = (ConfigReply_t *)reply;
518 u16 status;
519
520 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
521 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
522 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
523
524 pCfg->status = status;
525 if (status == MPI_IOCSTATUS_SUCCESS) {
526 if ((pReply->Header.PageType &
527 MPI_CONFIG_PAGETYPE_MASK) ==
528 MPI_CONFIG_PAGETYPE_EXTENDED) {
529 pCfg->cfghdr.ehdr->ExtPageLength =
530 le16_to_cpu(pReply->ExtPageLength);
531 pCfg->cfghdr.ehdr->ExtPageType =
532 pReply->ExtPageType;
533 }
534 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
535
536 /* If this is a regular header, save PageLength. */
537 /* LMP Do this better so not using a reserved field! */
538 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
539 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
540 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
541 }
542 }
543
544 /*
545 * Wake up the original calling thread
546 */
547 pCfg->wait_done = 1;
548 wake_up(&mpt_waitq);
549 }
550 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
551 /* we should be always getting a reply frame */
552 memcpy(ioc->persist_reply_frame, reply,
553 min(MPT_DEFAULT_FRAME_SIZE,
554 4*reply->u.reply.MsgLength));
555 del_timer(&ioc->persist_timer);
556 ioc->persist_wait_done = 1;
557 wake_up(&mpt_waitq);
558 } else {
559 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
560 ioc->name, func);
561 }
562
563 /*
564 * Conditionally tell caller to free the original
565 * EventNotification/EventAck/unexpected request frame!
566 */
567 return freereq;
568 }
569
570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
571 /**
572 * mpt_register - Register protocol-specific main callback handler.
573 * @cbfunc: callback function pointer
574 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
575 *
576 * This routine is called by a protocol-specific driver (SCSI host,
577 * LAN, SCSI target) to register its reply callback routine. Each
578 * protocol-specific driver must do this before it will be able to
579 * use any IOC resources, such as obtaining request frames.
580 *
581 * NOTES: The SCSI protocol driver currently calls this routine thrice
582 * in order to register separate callbacks; one for "normal" SCSI IO;
583 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
584 *
585 * Returns u8 valued "handle" in the range (and S.O.D. order)
586 * {N,...,7,6,5,...,1} if successful.
587 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
588 * considered an error by the caller.
589 */
590 u8
591 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
592 {
593 u8 cb_idx;
594 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
595
596 /*
597 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
598 * (slot/handle 0 is reserved!)
599 */
600 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
601 if (MptCallbacks[cb_idx] == NULL) {
602 MptCallbacks[cb_idx] = cbfunc;
603 MptDriverClass[cb_idx] = dclass;
604 MptEvHandlers[cb_idx] = NULL;
605 last_drv_idx = cb_idx;
606 break;
607 }
608 }
609
610 return last_drv_idx;
611 }
612
613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
614 /**
615 * mpt_deregister - Deregister a protocol drivers resources.
616 * @cb_idx: previously registered callback handle
617 *
618 * Each protocol-specific driver should call this routine when its
619 * module is unloaded.
620 */
621 void
622 mpt_deregister(u8 cb_idx)
623 {
624 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
625 MptCallbacks[cb_idx] = NULL;
626 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
627 MptEvHandlers[cb_idx] = NULL;
628
629 last_drv_idx++;
630 }
631 }
632
633 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
634 /**
635 * mpt_event_register - Register protocol-specific event callback handler.
636 * @cb_idx: previously registered (via mpt_register) callback handle
637 * @ev_cbfunc: callback function
638 *
639 * This routine can be called by one or more protocol-specific drivers
640 * if/when they choose to be notified of MPT events.
641 *
642 * Returns 0 for success.
643 */
644 int
645 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
646 {
647 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
648 return -1;
649
650 MptEvHandlers[cb_idx] = ev_cbfunc;
651 return 0;
652 }
653
654 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
655 /**
656 * mpt_event_deregister - Deregister protocol-specific event callback handler
657 * @cb_idx: previously registered callback handle
658 *
659 * Each protocol-specific driver should call this routine
660 * when it does not (or can no longer) handle events,
661 * or when its module is unloaded.
662 */
663 void
664 mpt_event_deregister(u8 cb_idx)
665 {
666 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
667 return;
668
669 MptEvHandlers[cb_idx] = NULL;
670 }
671
672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
673 /**
674 * mpt_reset_register - Register protocol-specific IOC reset handler.
675 * @cb_idx: previously registered (via mpt_register) callback handle
676 * @reset_func: reset function
677 *
678 * This routine can be called by one or more protocol-specific drivers
679 * if/when they choose to be notified of IOC resets.
680 *
681 * Returns 0 for success.
682 */
683 int
684 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
685 {
686 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
687 return -1;
688
689 MptResetHandlers[cb_idx] = reset_func;
690 return 0;
691 }
692
693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
694 /**
695 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
696 * @cb_idx: previously registered callback handle
697 *
698 * Each protocol-specific driver should call this routine
699 * when it does not (or can no longer) handle IOC reset handling,
700 * or when its module is unloaded.
701 */
702 void
703 mpt_reset_deregister(u8 cb_idx)
704 {
705 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
706 return;
707
708 MptResetHandlers[cb_idx] = NULL;
709 }
710
711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
712 /**
713 * mpt_device_driver_register - Register device driver hooks
714 * @dd_cbfunc: driver callbacks struct
715 * @cb_idx: MPT protocol driver index
716 */
717 int
718 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
719 {
720 MPT_ADAPTER *ioc;
721 const struct pci_device_id *id;
722
723 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
724 return -EINVAL;
725
726 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
727
728 /* call per pci device probe entry point */
729 list_for_each_entry(ioc, &ioc_list, list) {
730 id = ioc->pcidev->driver ?
731 ioc->pcidev->driver->id_table : NULL;
732 if (dd_cbfunc->probe)
733 dd_cbfunc->probe(ioc->pcidev, id);
734 }
735
736 return 0;
737 }
738
739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
740 /**
741 * mpt_device_driver_deregister - DeRegister device driver hooks
742 * @cb_idx: MPT protocol driver index
743 */
744 void
745 mpt_device_driver_deregister(u8 cb_idx)
746 {
747 struct mpt_pci_driver *dd_cbfunc;
748 MPT_ADAPTER *ioc;
749
750 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
751 return;
752
753 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
754
755 list_for_each_entry(ioc, &ioc_list, list) {
756 if (dd_cbfunc->remove)
757 dd_cbfunc->remove(ioc->pcidev);
758 }
759
760 MptDeviceDriverHandlers[cb_idx] = NULL;
761 }
762
763
764 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
765 /**
766 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
767 * @cb_idx: Handle of registered MPT protocol driver
768 * @ioc: Pointer to MPT adapter structure
769 *
770 * Obtain an MPT request frame from the pool (of 1024) that are
771 * allocated per MPT adapter.
772 *
773 * Returns pointer to a MPT request frame or %NULL if none are available
774 * or IOC is not active.
775 */
776 MPT_FRAME_HDR*
777 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
778 {
779 MPT_FRAME_HDR *mf;
780 unsigned long flags;
781 u16 req_idx; /* Request index */
782
783 /* validate handle and ioc identifier */
784
785 #ifdef MFCNT
786 if (!ioc->active)
787 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
788 "returning NULL!\n", ioc->name);
789 #endif
790
791 /* If interrupts are not attached, do not return a request frame */
792 if (!ioc->active)
793 return NULL;
794
795 spin_lock_irqsave(&ioc->FreeQlock, flags);
796 if (!list_empty(&ioc->FreeQ)) {
797 int req_offset;
798
799 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
800 u.frame.linkage.list);
801 list_del(&mf->u.frame.linkage.list);
802 mf->u.frame.linkage.arg1 = 0;
803 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
804 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
805 /* u16! */
806 req_idx = req_offset / ioc->req_sz;
807 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
808 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
809 /* Default, will be changed if necessary in SG generation */
810 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
811 #ifdef MFCNT
812 ioc->mfcnt++;
813 #endif
814 }
815 else
816 mf = NULL;
817 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
818
819 #ifdef MFCNT
820 if (mf == NULL)
821 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
822 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
823 ioc->req_depth);
824 mfcounter++;
825 if (mfcounter == PRINT_MF_COUNT)
826 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
827 ioc->mfcnt, ioc->req_depth);
828 #endif
829
830 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
831 ioc->name, cb_idx, ioc->id, mf));
832 return mf;
833 }
834
835 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
836 /**
837 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
838 * @cb_idx: Handle of registered MPT protocol driver
839 * @ioc: Pointer to MPT adapter structure
840 * @mf: Pointer to MPT request frame
841 *
842 * This routine posts an MPT request frame to the request post FIFO of a
843 * specific MPT adapter.
844 */
845 void
846 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
847 {
848 u32 mf_dma_addr;
849 int req_offset;
850 u16 req_idx; /* Request index */
851
852 /* ensure values are reset properly! */
853 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
854 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
855 /* u16! */
856 req_idx = req_offset / ioc->req_sz;
857 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
858 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
859
860 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
861
862 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
863 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
864 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
865 ioc->RequestNB[req_idx]));
866 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
867 }
868
869 /**
870 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
871 * @cb_idx: Handle of registered MPT protocol driver
872 * @ioc: Pointer to MPT adapter structure
873 * @mf: Pointer to MPT request frame
874 *
875 * Send a protocol-specific MPT request frame to an IOC using
876 * hi-priority request queue.
877 *
878 * This routine posts an MPT request frame to the request post FIFO of a
879 * specific MPT adapter.
880 **/
881 void
882 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
883 {
884 u32 mf_dma_addr;
885 int req_offset;
886 u16 req_idx; /* Request index */
887
888 /* ensure values are reset properly! */
889 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
890 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
891 req_idx = req_offset / ioc->req_sz;
892 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
893 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
894
895 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
896
897 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
898 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
899 ioc->name, mf_dma_addr, req_idx));
900 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
901 }
902
903 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
904 /**
905 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
906 * @handle: Handle of registered MPT protocol driver
907 * @ioc: Pointer to MPT adapter structure
908 * @mf: Pointer to MPT request frame
909 *
910 * This routine places a MPT request frame back on the MPT adapter's
911 * FreeQ.
912 */
913 void
914 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
915 {
916 unsigned long flags;
917
918 /* Put Request back on FreeQ! */
919 spin_lock_irqsave(&ioc->FreeQlock, flags);
920 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
921 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
922 #ifdef MFCNT
923 ioc->mfcnt--;
924 #endif
925 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
926 }
927
928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
929 /**
930 * mpt_add_sge - Place a simple SGE at address pAddr.
931 * @pAddr: virtual address for SGE
932 * @flagslength: SGE flags and data transfer length
933 * @dma_addr: Physical address
934 *
935 * This routine places a MPT request frame back on the MPT adapter's
936 * FreeQ.
937 */
938 void
939 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
940 {
941 if (sizeof(dma_addr_t) == sizeof(u64)) {
942 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
943 u32 tmp = dma_addr & 0xFFFFFFFF;
944
945 pSge->FlagsLength = cpu_to_le32(flagslength);
946 pSge->Address.Low = cpu_to_le32(tmp);
947 tmp = (u32) ((u64)dma_addr >> 32);
948 pSge->Address.High = cpu_to_le32(tmp);
949
950 } else {
951 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
952 pSge->FlagsLength = cpu_to_le32(flagslength);
953 pSge->Address = cpu_to_le32(dma_addr);
954 }
955 }
956
957 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
958 /**
959 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
960 * @cb_idx: Handle of registered MPT protocol driver
961 * @ioc: Pointer to MPT adapter structure
962 * @reqBytes: Size of the request in bytes
963 * @req: Pointer to MPT request frame
964 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
965 *
966 * This routine is used exclusively to send MptScsiTaskMgmt
967 * requests since they are required to be sent via doorbell handshake.
968 *
969 * NOTE: It is the callers responsibility to byte-swap fields in the
970 * request which are greater than 1 byte in size.
971 *
972 * Returns 0 for success, non-zero for failure.
973 */
974 int
975 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
976 {
977 int r = 0;
978 u8 *req_as_bytes;
979 int ii;
980
981 /* State is known to be good upon entering
982 * this function so issue the bus reset
983 * request.
984 */
985
986 /*
987 * Emulate what mpt_put_msg_frame() does /wrt to sanity
988 * setting cb_idx/req_idx. But ONLY if this request
989 * is in proper (pre-alloc'd) request buffer range...
990 */
991 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
992 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
993 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
994 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
995 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
996 }
997
998 /* Make sure there are no doorbells */
999 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1000
1001 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1002 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1003 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1004
1005 /* Wait for IOC doorbell int */
1006 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1007 return ii;
1008 }
1009
1010 /* Read doorbell and check for active bit */
1011 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1012 return -5;
1013
1014 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1015 ioc->name, ii));
1016
1017 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1018
1019 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1020 return -2;
1021 }
1022
1023 /* Send request via doorbell handshake */
1024 req_as_bytes = (u8 *) req;
1025 for (ii = 0; ii < reqBytes/4; ii++) {
1026 u32 word;
1027
1028 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1029 (req_as_bytes[(ii*4) + 1] << 8) |
1030 (req_as_bytes[(ii*4) + 2] << 16) |
1031 (req_as_bytes[(ii*4) + 3] << 24));
1032 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1033 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1034 r = -3;
1035 break;
1036 }
1037 }
1038
1039 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1040 r = 0;
1041 else
1042 r = -4;
1043
1044 /* Make sure there are no doorbells */
1045 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1046
1047 return r;
1048 }
1049
1050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1051 /**
1052 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1053 * @ioc: Pointer to MPT adapter structure
1054 * @access_control_value: define bits below
1055 * @sleepFlag: Specifies whether the process can sleep
1056 *
1057 * Provides mechanism for the host driver to control the IOC's
1058 * Host Page Buffer access.
1059 *
1060 * Access Control Value - bits[15:12]
1061 * 0h Reserved
1062 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1063 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1064 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1065 *
1066 * Returns 0 for success, non-zero for failure.
1067 */
1068
1069 static int
1070 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1071 {
1072 int r = 0;
1073
1074 /* return if in use */
1075 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1076 & MPI_DOORBELL_ACTIVE)
1077 return -1;
1078
1079 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1080
1081 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1082 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1083 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1084 (access_control_value<<12)));
1085
1086 /* Wait for IOC to clear Doorbell Status bit */
1087 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1088 return -2;
1089 }else
1090 return 0;
1091 }
1092
1093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1094 /**
1095 * mpt_host_page_alloc - allocate system memory for the fw
1096 * @ioc: Pointer to pointer to IOC adapter
1097 * @ioc_init: Pointer to ioc init config page
1098 *
1099 * If we already allocated memory in past, then resend the same pointer.
1100 * Returns 0 for success, non-zero for failure.
1101 */
1102 static int
1103 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1104 {
1105 char *psge;
1106 int flags_length;
1107 u32 host_page_buffer_sz=0;
1108
1109 if(!ioc->HostPageBuffer) {
1110
1111 host_page_buffer_sz =
1112 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1113
1114 if(!host_page_buffer_sz)
1115 return 0; /* fw doesn't need any host buffers */
1116
1117 /* spin till we get enough memory */
1118 while(host_page_buffer_sz > 0) {
1119
1120 if((ioc->HostPageBuffer = pci_alloc_consistent(
1121 ioc->pcidev,
1122 host_page_buffer_sz,
1123 &ioc->HostPageBuffer_dma)) != NULL) {
1124
1125 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1126 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1127 ioc->name, ioc->HostPageBuffer,
1128 (u32)ioc->HostPageBuffer_dma,
1129 host_page_buffer_sz));
1130 ioc->alloc_total += host_page_buffer_sz;
1131 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1132 break;
1133 }
1134
1135 host_page_buffer_sz -= (4*1024);
1136 }
1137 }
1138
1139 if(!ioc->HostPageBuffer) {
1140 printk(MYIOC_s_ERR_FMT
1141 "Failed to alloc memory for host_page_buffer!\n",
1142 ioc->name);
1143 return -999;
1144 }
1145
1146 psge = (char *)&ioc_init->HostPageBufferSGE;
1147 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1148 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1149 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1150 MPI_SGE_FLAGS_HOST_TO_IOC |
1151 MPI_SGE_FLAGS_END_OF_BUFFER;
1152 if (sizeof(dma_addr_t) == sizeof(u64)) {
1153 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1154 }
1155 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1156 flags_length |= ioc->HostPageBuffer_sz;
1157 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1158 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1159
1160 return 0;
1161 }
1162
1163 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1164 /**
1165 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1166 * @iocid: IOC unique identifier (integer)
1167 * @iocpp: Pointer to pointer to IOC adapter
1168 *
1169 * Given a unique IOC identifier, set pointer to the associated MPT
1170 * adapter structure.
1171 *
1172 * Returns iocid and sets iocpp if iocid is found.
1173 * Returns -1 if iocid is not found.
1174 */
1175 int
1176 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1177 {
1178 MPT_ADAPTER *ioc;
1179
1180 list_for_each_entry(ioc,&ioc_list,list) {
1181 if (ioc->id == iocid) {
1182 *iocpp =ioc;
1183 return iocid;
1184 }
1185 }
1186
1187 *iocpp = NULL;
1188 return -1;
1189 }
1190
1191 /**
1192 * mpt_get_product_name - returns product string
1193 * @vendor: pci vendor id
1194 * @device: pci device id
1195 * @revision: pci revision id
1196 * @prod_name: string returned
1197 *
1198 * Returns product string displayed when driver loads,
1199 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1200 *
1201 **/
1202 static void
1203 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1204 {
1205 char *product_str = NULL;
1206
1207 if (vendor == PCI_VENDOR_ID_BROCADE) {
1208 switch (device)
1209 {
1210 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1211 switch (revision)
1212 {
1213 case 0x00:
1214 product_str = "BRE040 A0";
1215 break;
1216 case 0x01:
1217 product_str = "BRE040 A1";
1218 break;
1219 default:
1220 product_str = "BRE040";
1221 break;
1222 }
1223 break;
1224 }
1225 goto out;
1226 }
1227
1228 switch (device)
1229 {
1230 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1231 product_str = "LSIFC909 B1";
1232 break;
1233 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1234 product_str = "LSIFC919 B0";
1235 break;
1236 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1237 product_str = "LSIFC929 B0";
1238 break;
1239 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1240 if (revision < 0x80)
1241 product_str = "LSIFC919X A0";
1242 else
1243 product_str = "LSIFC919XL A1";
1244 break;
1245 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1246 if (revision < 0x80)
1247 product_str = "LSIFC929X A0";
1248 else
1249 product_str = "LSIFC929XL A1";
1250 break;
1251 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1252 product_str = "LSIFC939X A1";
1253 break;
1254 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1255 product_str = "LSIFC949X A1";
1256 break;
1257 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1258 switch (revision)
1259 {
1260 case 0x00:
1261 product_str = "LSIFC949E A0";
1262 break;
1263 case 0x01:
1264 product_str = "LSIFC949E A1";
1265 break;
1266 default:
1267 product_str = "LSIFC949E";
1268 break;
1269 }
1270 break;
1271 case MPI_MANUFACTPAGE_DEVID_53C1030:
1272 switch (revision)
1273 {
1274 case 0x00:
1275 product_str = "LSI53C1030 A0";
1276 break;
1277 case 0x01:
1278 product_str = "LSI53C1030 B0";
1279 break;
1280 case 0x03:
1281 product_str = "LSI53C1030 B1";
1282 break;
1283 case 0x07:
1284 product_str = "LSI53C1030 B2";
1285 break;
1286 case 0x08:
1287 product_str = "LSI53C1030 C0";
1288 break;
1289 case 0x80:
1290 product_str = "LSI53C1030T A0";
1291 break;
1292 case 0x83:
1293 product_str = "LSI53C1030T A2";
1294 break;
1295 case 0x87:
1296 product_str = "LSI53C1030T A3";
1297 break;
1298 case 0xc1:
1299 product_str = "LSI53C1020A A1";
1300 break;
1301 default:
1302 product_str = "LSI53C1030";
1303 break;
1304 }
1305 break;
1306 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1307 switch (revision)
1308 {
1309 case 0x03:
1310 product_str = "LSI53C1035 A2";
1311 break;
1312 case 0x04:
1313 product_str = "LSI53C1035 B0";
1314 break;
1315 default:
1316 product_str = "LSI53C1035";
1317 break;
1318 }
1319 break;
1320 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1321 switch (revision)
1322 {
1323 case 0x00:
1324 product_str = "LSISAS1064 A1";
1325 break;
1326 case 0x01:
1327 product_str = "LSISAS1064 A2";
1328 break;
1329 case 0x02:
1330 product_str = "LSISAS1064 A3";
1331 break;
1332 case 0x03:
1333 product_str = "LSISAS1064 A4";
1334 break;
1335 default:
1336 product_str = "LSISAS1064";
1337 break;
1338 }
1339 break;
1340 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1341 switch (revision)
1342 {
1343 case 0x00:
1344 product_str = "LSISAS1064E A0";
1345 break;
1346 case 0x01:
1347 product_str = "LSISAS1064E B0";
1348 break;
1349 case 0x02:
1350 product_str = "LSISAS1064E B1";
1351 break;
1352 case 0x04:
1353 product_str = "LSISAS1064E B2";
1354 break;
1355 case 0x08:
1356 product_str = "LSISAS1064E B3";
1357 break;
1358 default:
1359 product_str = "LSISAS1064E";
1360 break;
1361 }
1362 break;
1363 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1364 switch (revision)
1365 {
1366 case 0x00:
1367 product_str = "LSISAS1068 A0";
1368 break;
1369 case 0x01:
1370 product_str = "LSISAS1068 B0";
1371 break;
1372 case 0x02:
1373 product_str = "LSISAS1068 B1";
1374 break;
1375 default:
1376 product_str = "LSISAS1068";
1377 break;
1378 }
1379 break;
1380 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1381 switch (revision)
1382 {
1383 case 0x00:
1384 product_str = "LSISAS1068E A0";
1385 break;
1386 case 0x01:
1387 product_str = "LSISAS1068E B0";
1388 break;
1389 case 0x02:
1390 product_str = "LSISAS1068E B1";
1391 break;
1392 case 0x04:
1393 product_str = "LSISAS1068E B2";
1394 break;
1395 case 0x08:
1396 product_str = "LSISAS1068E B3";
1397 break;
1398 default:
1399 product_str = "LSISAS1068E";
1400 break;
1401 }
1402 break;
1403 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1404 switch (revision)
1405 {
1406 case 0x00:
1407 product_str = "LSISAS1078 A0";
1408 break;
1409 case 0x01:
1410 product_str = "LSISAS1078 B0";
1411 break;
1412 case 0x02:
1413 product_str = "LSISAS1078 C0";
1414 break;
1415 case 0x03:
1416 product_str = "LSISAS1078 C1";
1417 break;
1418 case 0x04:
1419 product_str = "LSISAS1078 C2";
1420 break;
1421 default:
1422 product_str = "LSISAS1078";
1423 break;
1424 }
1425 break;
1426 }
1427
1428 out:
1429 if (product_str)
1430 sprintf(prod_name, "%s", product_str);
1431 }
1432
1433 /**
1434 * mpt_mapresources - map in memory mapped io
1435 * @ioc: Pointer to pointer to IOC adapter
1436 *
1437 **/
1438 static int
1439 mpt_mapresources(MPT_ADAPTER *ioc)
1440 {
1441 u8 __iomem *mem;
1442 int ii;
1443 unsigned long mem_phys;
1444 unsigned long port;
1445 u32 msize;
1446 u32 psize;
1447 u8 revision;
1448 int r = -ENODEV;
1449 struct pci_dev *pdev;
1450
1451 pdev = ioc->pcidev;
1452 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1453 if (pci_enable_device_mem(pdev)) {
1454 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1455 "failed\n", ioc->name);
1456 return r;
1457 }
1458 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1459 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1460 "MEM failed\n", ioc->name);
1461 return r;
1462 }
1463
1464 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1465
1466 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
1467 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1468 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1469 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1470 ioc->name));
1471 } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
1472 && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
1473 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1474 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1475 ioc->name));
1476 } else {
1477 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1478 ioc->name, pci_name(pdev));
1479 pci_release_selected_regions(pdev, ioc->bars);
1480 return r;
1481 }
1482
1483 mem_phys = msize = 0;
1484 port = psize = 0;
1485 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1486 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1487 if (psize)
1488 continue;
1489 /* Get I/O space! */
1490 port = pci_resource_start(pdev, ii);
1491 psize = pci_resource_len(pdev, ii);
1492 } else {
1493 if (msize)
1494 continue;
1495 /* Get memmap */
1496 mem_phys = pci_resource_start(pdev, ii);
1497 msize = pci_resource_len(pdev, ii);
1498 }
1499 }
1500 ioc->mem_size = msize;
1501
1502 mem = NULL;
1503 /* Get logical ptr for PciMem0 space */
1504 /*mem = ioremap(mem_phys, msize);*/
1505 mem = ioremap(mem_phys, msize);
1506 if (mem == NULL) {
1507 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1508 " memory!\n", ioc->name);
1509 return -EINVAL;
1510 }
1511 ioc->memmap = mem;
1512 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1513 ioc->name, mem, mem_phys));
1514
1515 ioc->mem_phys = mem_phys;
1516 ioc->chip = (SYSIF_REGS __iomem *)mem;
1517
1518 /* Save Port IO values in case we need to do downloadboot */
1519 ioc->pio_mem_phys = port;
1520 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1521
1522 return 0;
1523 }
1524
1525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1526 /**
1527 * mpt_attach - Install a PCI intelligent MPT adapter.
1528 * @pdev: Pointer to pci_dev structure
1529 * @id: PCI device ID information
1530 *
1531 * This routine performs all the steps necessary to bring the IOC of
1532 * a MPT adapter to a OPERATIONAL state. This includes registering
1533 * memory regions, registering the interrupt, and allocating request
1534 * and reply memory pools.
1535 *
1536 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1537 * MPT adapter.
1538 *
1539 * Returns 0 for success, non-zero for failure.
1540 *
1541 * TODO: Add support for polled controllers
1542 */
1543 int
1544 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1545 {
1546 MPT_ADAPTER *ioc;
1547 u8 cb_idx;
1548 int r = -ENODEV;
1549 u8 revision;
1550 u8 pcixcmd;
1551 static int mpt_ids = 0;
1552 #ifdef CONFIG_PROC_FS
1553 struct proc_dir_entry *dent, *ent;
1554 #endif
1555
1556 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1557 if (ioc == NULL) {
1558 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1559 return -ENOMEM;
1560 }
1561
1562 ioc->id = mpt_ids++;
1563 sprintf(ioc->name, "ioc%d", ioc->id);
1564
1565 /*
1566 * set initial debug level
1567 * (refer to mptdebug.h)
1568 *
1569 */
1570 ioc->debug_level = mpt_debug_level;
1571 if (mpt_debug_level)
1572 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1573
1574 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1575
1576 ioc->pcidev = pdev;
1577 if (mpt_mapresources(ioc)) {
1578 kfree(ioc);
1579 return r;
1580 }
1581
1582 ioc->alloc_total = sizeof(MPT_ADAPTER);
1583 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1584 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1585
1586 ioc->pcidev = pdev;
1587 ioc->diagPending = 0;
1588 spin_lock_init(&ioc->diagLock);
1589 spin_lock_init(&ioc->initializing_hba_lock);
1590
1591 /* Initialize the event logging.
1592 */
1593 ioc->eventTypes = 0; /* None */
1594 ioc->eventContext = 0;
1595 ioc->eventLogSize = 0;
1596 ioc->events = NULL;
1597
1598 #ifdef MFCNT
1599 ioc->mfcnt = 0;
1600 #endif
1601
1602 ioc->cached_fw = NULL;
1603
1604 /* Initilize SCSI Config Data structure
1605 */
1606 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1607
1608 /* Initialize the running configQ head.
1609 */
1610 INIT_LIST_HEAD(&ioc->configQ);
1611
1612 /* Initialize the fc rport list head.
1613 */
1614 INIT_LIST_HEAD(&ioc->fc_rports);
1615
1616 /* Find lookup slot. */
1617 INIT_LIST_HEAD(&ioc->list);
1618
1619 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1620 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1621
1622 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1623 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1624
1625 switch (pdev->device)
1626 {
1627 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1628 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1629 ioc->errata_flag_1064 = 1;
1630 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1631 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1632 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1633 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1634 ioc->bus_type = FC;
1635 break;
1636
1637 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1638 if (revision < XL_929) {
1639 /* 929X Chip Fix. Set Split transactions level
1640 * for PCIX. Set MOST bits to zero.
1641 */
1642 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1643 pcixcmd &= 0x8F;
1644 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1645 } else {
1646 /* 929XL Chip Fix. Set MMRBC to 0x08.
1647 */
1648 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1649 pcixcmd |= 0x08;
1650 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1651 }
1652 ioc->bus_type = FC;
1653 break;
1654
1655 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1656 /* 919X Chip Fix. Set Split transactions level
1657 * for PCIX. Set MOST bits to zero.
1658 */
1659 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1660 pcixcmd &= 0x8F;
1661 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1662 ioc->bus_type = FC;
1663 break;
1664
1665 case MPI_MANUFACTPAGE_DEVID_53C1030:
1666 /* 1030 Chip Fix. Disable Split transactions
1667 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1668 */
1669 if (revision < C0_1030) {
1670 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1671 pcixcmd &= 0x8F;
1672 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1673 }
1674
1675 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1676 ioc->bus_type = SPI;
1677 break;
1678
1679 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1680 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1681 ioc->errata_flag_1064 = 1;
1682
1683 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1684 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1685 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1686 ioc->bus_type = SAS;
1687 }
1688
1689 if (mpt_msi_enable == -1) {
1690 /* Enable on SAS, disable on FC and SPI */
1691 if (ioc->bus_type == SAS)
1692 ioc->msi_enable = 1;
1693 else
1694 ioc->msi_enable = 0;
1695 } else
1696 /* follow flag: 0 - disable; 1 - enable */
1697 ioc->msi_enable = mpt_msi_enable;
1698
1699 if (ioc->errata_flag_1064)
1700 pci_disable_io_access(pdev);
1701
1702 spin_lock_init(&ioc->FreeQlock);
1703
1704 /* Disable all! */
1705 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1706 ioc->active = 0;
1707 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1708
1709 /* Set IOC ptr in the pcidev's driver data. */
1710 pci_set_drvdata(ioc->pcidev, ioc);
1711
1712 /* Set lookup ptr. */
1713 list_add_tail(&ioc->list, &ioc_list);
1714
1715 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1716 */
1717 mpt_detect_bound_ports(ioc, pdev);
1718
1719 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1720 CAN_SLEEP)) != 0){
1721 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1722 ioc->name, r);
1723
1724 list_del(&ioc->list);
1725 if (ioc->alt_ioc)
1726 ioc->alt_ioc->alt_ioc = NULL;
1727 iounmap(ioc->memmap);
1728 if (r != -5)
1729 pci_release_selected_regions(pdev, ioc->bars);
1730 kfree(ioc);
1731 pci_set_drvdata(pdev, NULL);
1732 return r;
1733 }
1734
1735 /* call per device driver probe entry point */
1736 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1737 if(MptDeviceDriverHandlers[cb_idx] &&
1738 MptDeviceDriverHandlers[cb_idx]->probe) {
1739 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1740 }
1741 }
1742
1743 #ifdef CONFIG_PROC_FS
1744 /*
1745 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1746 */
1747 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1748 if (dent) {
1749 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1750 if (ent) {
1751 ent->read_proc = procmpt_iocinfo_read;
1752 ent->data = ioc;
1753 }
1754 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1755 if (ent) {
1756 ent->read_proc = procmpt_summary_read;
1757 ent->data = ioc;
1758 }
1759 }
1760 #endif
1761
1762 return 0;
1763 }
1764
1765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1766 /**
1767 * mpt_detach - Remove a PCI intelligent MPT adapter.
1768 * @pdev: Pointer to pci_dev structure
1769 */
1770
1771 void
1772 mpt_detach(struct pci_dev *pdev)
1773 {
1774 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1775 char pname[32];
1776 u8 cb_idx;
1777
1778 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1779 remove_proc_entry(pname, NULL);
1780 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1781 remove_proc_entry(pname, NULL);
1782 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1783 remove_proc_entry(pname, NULL);
1784
1785 /* call per device driver remove entry point */
1786 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1787 if(MptDeviceDriverHandlers[cb_idx] &&
1788 MptDeviceDriverHandlers[cb_idx]->remove) {
1789 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1790 }
1791 }
1792
1793 /* Disable interrupts! */
1794 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1795
1796 ioc->active = 0;
1797 synchronize_irq(pdev->irq);
1798
1799 /* Clear any lingering interrupt */
1800 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1801
1802 CHIPREG_READ32(&ioc->chip->IntStatus);
1803
1804 mpt_adapter_dispose(ioc);
1805
1806 pci_set_drvdata(pdev, NULL);
1807 }
1808
1809 /**************************************************************************
1810 * Power Management
1811 */
1812 #ifdef CONFIG_PM
1813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1814 /**
1815 * mpt_suspend - Fusion MPT base driver suspend routine.
1816 * @pdev: Pointer to pci_dev structure
1817 * @state: new state to enter
1818 */
1819 int
1820 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1821 {
1822 u32 device_state;
1823 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1824
1825 device_state = pci_choose_state(pdev, state);
1826 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
1827 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1828 device_state);
1829
1830 /* put ioc into READY_STATE */
1831 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1832 printk(MYIOC_s_ERR_FMT
1833 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1834 }
1835
1836 /* disable interrupts */
1837 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1838 ioc->active = 0;
1839
1840 /* Clear any lingering interrupt */
1841 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1842
1843 free_irq(ioc->pci_irq, ioc);
1844 if (ioc->msi_enable)
1845 pci_disable_msi(ioc->pcidev);
1846 ioc->pci_irq = -1;
1847 pci_save_state(pdev);
1848 pci_disable_device(pdev);
1849 pci_release_selected_regions(pdev, ioc->bars);
1850 pci_set_power_state(pdev, device_state);
1851 return 0;
1852 }
1853
1854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1855 /**
1856 * mpt_resume - Fusion MPT base driver resume routine.
1857 * @pdev: Pointer to pci_dev structure
1858 */
1859 int
1860 mpt_resume(struct pci_dev *pdev)
1861 {
1862 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1863 u32 device_state = pdev->current_state;
1864 int recovery_state;
1865 int err;
1866
1867 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
1868 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1869 device_state);
1870
1871 pci_set_power_state(pdev, PCI_D0);
1872 pci_enable_wake(pdev, PCI_D0, 0);
1873 pci_restore_state(pdev);
1874 ioc->pcidev = pdev;
1875 err = mpt_mapresources(ioc);
1876 if (err)
1877 return err;
1878
1879 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1880 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1881 CHIPREG_READ32(&ioc->chip->Doorbell));
1882
1883 /*
1884 * Errata workaround for SAS pci express:
1885 * Upon returning to the D0 state, the contents of the doorbell will be
1886 * stale data, and this will incorrectly signal to the host driver that
1887 * the firmware is ready to process mpt commands. The workaround is
1888 * to issue a diagnostic reset.
1889 */
1890 if (ioc->bus_type == SAS && (pdev->device ==
1891 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
1892 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
1893 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
1894 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
1895 ioc->name);
1896 goto out;
1897 }
1898 }
1899
1900 /* bring ioc to operational state */
1901 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
1902 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1903 CAN_SLEEP);
1904 if (recovery_state != 0)
1905 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
1906 "error:[%x]\n", ioc->name, recovery_state);
1907 else
1908 printk(MYIOC_s_INFO_FMT
1909 "pci-resume: success\n", ioc->name);
1910 out:
1911 return 0;
1912
1913 }
1914 #endif
1915
1916 static int
1917 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1918 {
1919 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1920 ioc->bus_type != SPI) ||
1921 (MptDriverClass[index] == MPTFC_DRIVER &&
1922 ioc->bus_type != FC) ||
1923 (MptDriverClass[index] == MPTSAS_DRIVER &&
1924 ioc->bus_type != SAS))
1925 /* make sure we only call the relevant reset handler
1926 * for the bus */
1927 return 0;
1928 return (MptResetHandlers[index])(ioc, reset_phase);
1929 }
1930
1931 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1932 /**
1933 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1934 * @ioc: Pointer to MPT adapter structure
1935 * @reason: Event word / reason
1936 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1937 *
1938 * This routine performs all the steps necessary to bring the IOC
1939 * to a OPERATIONAL state.
1940 *
1941 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1942 * MPT adapter.
1943 *
1944 * Returns:
1945 * 0 for success
1946 * -1 if failed to get board READY
1947 * -2 if READY but IOCFacts Failed
1948 * -3 if READY but PrimeIOCFifos Failed
1949 * -4 if READY but IOCInit Failed
1950 * -5 if failed to enable_device and/or request_selected_regions
1951 * -6 if failed to upload firmware
1952 */
1953 static int
1954 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1955 {
1956 int hard_reset_done = 0;
1957 int alt_ioc_ready = 0;
1958 int hard;
1959 int rc=0;
1960 int ii;
1961 u8 cb_idx;
1962 int handlers;
1963 int ret = 0;
1964 int reset_alt_ioc_active = 0;
1965 int irq_allocated = 0;
1966 u8 *a;
1967
1968 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
1969 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1970
1971 /* Disable reply interrupts (also blocks FreeQ) */
1972 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1973 ioc->active = 0;
1974
1975 if (ioc->alt_ioc) {
1976 if (ioc->alt_ioc->active)
1977 reset_alt_ioc_active = 1;
1978
1979 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1980 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1981 ioc->alt_ioc->active = 0;
1982 }
1983
1984 hard = 1;
1985 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1986 hard = 0;
1987
1988 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1989 if (hard_reset_done == -4) {
1990 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
1991 ioc->name);
1992
1993 if (reset_alt_ioc_active && ioc->alt_ioc) {
1994 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1995 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1996 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
1997 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1998 ioc->alt_ioc->active = 1;
1999 }
2000
2001 } else {
2002 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
2003 }
2004 return -1;
2005 }
2006
2007 /* hard_reset_done = 0 if a soft reset was performed
2008 * and 1 if a hard reset was performed.
2009 */
2010 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2011 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2012 alt_ioc_ready = 1;
2013 else
2014 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
2015 }
2016
2017 for (ii=0; ii<5; ii++) {
2018 /* Get IOC facts! Allow 5 retries */
2019 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2020 break;
2021 }
2022
2023
2024 if (ii == 5) {
2025 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2026 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2027 ret = -2;
2028 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2029 MptDisplayIocCapabilities(ioc);
2030 }
2031
2032 if (alt_ioc_ready) {
2033 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2034 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2035 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
2036 /* Retry - alt IOC was initialized once
2037 */
2038 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2039 }
2040 if (rc) {
2041 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2042 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2043 alt_ioc_ready = 0;
2044 reset_alt_ioc_active = 0;
2045 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2046 MptDisplayIocCapabilities(ioc->alt_ioc);
2047 }
2048 }
2049
2050 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2051 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2052 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2053 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2054 IORESOURCE_IO);
2055 if (pci_enable_device(ioc->pcidev))
2056 return -5;
2057 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2058 "mpt"))
2059 return -5;
2060 }
2061
2062 /*
2063 * Device is reset now. It must have de-asserted the interrupt line
2064 * (if it was asserted) and it should be safe to register for the
2065 * interrupt now.
2066 */
2067 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2068 ioc->pci_irq = -1;
2069 if (ioc->pcidev->irq) {
2070 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2071 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2072 ioc->name);
2073 else
2074 ioc->msi_enable = 0;
2075 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2076 IRQF_SHARED, ioc->name, ioc);
2077 if (rc < 0) {
2078 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2079 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2080 if (ioc->msi_enable)
2081 pci_disable_msi(ioc->pcidev);
2082 return -EBUSY;
2083 }
2084 irq_allocated = 1;
2085 ioc->pci_irq = ioc->pcidev->irq;
2086 pci_set_master(ioc->pcidev); /* ?? */
2087 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2088 "%d\n", ioc->name, ioc->pcidev->irq));
2089 }
2090 }
2091
2092 /* Prime reply & request queues!
2093 * (mucho alloc's) Must be done prior to
2094 * init as upper addresses are needed for init.
2095 * If fails, continue with alt-ioc processing
2096 */
2097 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2098 ret = -3;
2099
2100 /* May need to check/upload firmware & data here!
2101 * If fails, continue with alt-ioc processing
2102 */
2103 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2104 ret = -4;
2105 // NEW!
2106 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2107 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2108 ioc->alt_ioc->name, rc);
2109 alt_ioc_ready = 0;
2110 reset_alt_ioc_active = 0;
2111 }
2112
2113 if (alt_ioc_ready) {
2114 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2115 alt_ioc_ready = 0;
2116 reset_alt_ioc_active = 0;
2117 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2118 ioc->alt_ioc->name, rc);
2119 }
2120 }
2121
2122 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2123 if (ioc->upload_fw) {
2124 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2125 "firmware upload required!\n", ioc->name));
2126
2127 /* Controller is not operational, cannot do upload
2128 */
2129 if (ret == 0) {
2130 rc = mpt_do_upload(ioc, sleepFlag);
2131 if (rc == 0) {
2132 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2133 /*
2134 * Maintain only one pointer to FW memory
2135 * so there will not be two attempt to
2136 * downloadboot onboard dual function
2137 * chips (mpt_adapter_disable,
2138 * mpt_diag_reset)
2139 */
2140 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2141 "mpt_upload: alt_%s has cached_fw=%p \n",
2142 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2143 ioc->cached_fw = NULL;
2144 }
2145 } else {
2146 printk(MYIOC_s_WARN_FMT
2147 "firmware upload failure!\n", ioc->name);
2148 ret = -6;
2149 }
2150 }
2151 }
2152 }
2153
2154 if (ret == 0) {
2155 /* Enable! (reply interrupt) */
2156 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2157 ioc->active = 1;
2158 }
2159
2160 if (reset_alt_ioc_active && ioc->alt_ioc) {
2161 /* (re)Enable alt-IOC! (reply interrupt) */
2162 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2163 ioc->alt_ioc->name));
2164 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2165 ioc->alt_ioc->active = 1;
2166 }
2167
2168 /* Enable MPT base driver management of EventNotification
2169 * and EventAck handling.
2170 */
2171 if ((ret == 0) && (!ioc->facts.EventState))
2172 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2173
2174 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2175 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2176
2177 /* Add additional "reason" check before call to GetLanConfigPages
2178 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2179 * recursive scenario; GetLanConfigPages times out, timer expired
2180 * routine calls HardResetHandler, which calls into here again,
2181 * and we try GetLanConfigPages again...
2182 */
2183 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2184
2185 /*
2186 * Initalize link list for inactive raid volumes.
2187 */
2188 mutex_init(&ioc->raid_data.inactive_list_mutex);
2189 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2190
2191 if (ioc->bus_type == SAS) {
2192
2193 /* clear persistency table */
2194 if(ioc->facts.IOCExceptions &
2195 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2196 ret = mptbase_sas_persist_operation(ioc,
2197 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2198 if(ret != 0)
2199 goto out;
2200 }
2201
2202 /* Find IM volumes
2203 */
2204 mpt_findImVolumes(ioc);
2205
2206 } else if (ioc->bus_type == FC) {
2207 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2208 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2209 /*
2210 * Pre-fetch the ports LAN MAC address!
2211 * (LANPage1_t stuff)
2212 */
2213 (void) GetLanConfigPages(ioc);
2214 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2215 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2216 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2217 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2218
2219 }
2220 } else {
2221 /* Get NVRAM and adapter maximums from SPP 0 and 2
2222 */
2223 mpt_GetScsiPortSettings(ioc, 0);
2224
2225 /* Get version and length of SDP 1
2226 */
2227 mpt_readScsiDevicePageHeaders(ioc, 0);
2228
2229 /* Find IM volumes
2230 */
2231 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2232 mpt_findImVolumes(ioc);
2233
2234 /* Check, and possibly reset, the coalescing value
2235 */
2236 mpt_read_ioc_pg_1(ioc);
2237
2238 mpt_read_ioc_pg_4(ioc);
2239 }
2240
2241 GetIoUnitPage2(ioc);
2242 mpt_get_manufacturing_pg_0(ioc);
2243 }
2244
2245 /*
2246 * Call each currently registered protocol IOC reset handler
2247 * with post-reset indication.
2248 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2249 * MptResetHandlers[] registered yet.
2250 */
2251 if (hard_reset_done) {
2252 rc = handlers = 0;
2253 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2254 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2255 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2256 "Calling IOC post_reset handler #%d\n",
2257 ioc->name, cb_idx));
2258 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2259 handlers++;
2260 }
2261
2262 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2263 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2264 "Calling IOC post_reset handler #%d\n",
2265 ioc->alt_ioc->name, cb_idx));
2266 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2267 handlers++;
2268 }
2269 }
2270 /* FIXME? Examine results here? */
2271 }
2272
2273 out:
2274 if ((ret != 0) && irq_allocated) {
2275 free_irq(ioc->pci_irq, ioc);
2276 if (ioc->msi_enable)
2277 pci_disable_msi(ioc->pcidev);
2278 }
2279 return ret;
2280 }
2281
2282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2283 /**
2284 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2285 * @ioc: Pointer to MPT adapter structure
2286 * @pdev: Pointer to (struct pci_dev) structure
2287 *
2288 * Search for PCI bus/dev_function which matches
2289 * PCI bus/dev_function (+/-1) for newly discovered 929,
2290 * 929X, 1030 or 1035.
2291 *
2292 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2293 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2294 */
2295 static void
2296 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2297 {
2298 struct pci_dev *peer=NULL;
2299 unsigned int slot = PCI_SLOT(pdev->devfn);
2300 unsigned int func = PCI_FUNC(pdev->devfn);
2301 MPT_ADAPTER *ioc_srch;
2302
2303 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2304 " searching for devfn match on %x or %x\n",
2305 ioc->name, pci_name(pdev), pdev->bus->number,
2306 pdev->devfn, func-1, func+1));
2307
2308 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2309 if (!peer) {
2310 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2311 if (!peer)
2312 return;
2313 }
2314
2315 list_for_each_entry(ioc_srch, &ioc_list, list) {
2316 struct pci_dev *_pcidev = ioc_srch->pcidev;
2317 if (_pcidev == peer) {
2318 /* Paranoia checks */
2319 if (ioc->alt_ioc != NULL) {
2320 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2321 ioc->name, ioc->alt_ioc->name);
2322 break;
2323 } else if (ioc_srch->alt_ioc != NULL) {
2324 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2325 ioc_srch->name, ioc_srch->alt_ioc->name);
2326 break;
2327 }
2328 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2329 ioc->name, ioc_srch->name));
2330 ioc_srch->alt_ioc = ioc;
2331 ioc->alt_ioc = ioc_srch;
2332 }
2333 }
2334 pci_dev_put(peer);
2335 }
2336
2337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2338 /**
2339 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2340 * @ioc: Pointer to MPT adapter structure
2341 */
2342 static void
2343 mpt_adapter_disable(MPT_ADAPTER *ioc)
2344 {
2345 int sz;
2346 int ret;
2347
2348 if (ioc->cached_fw != NULL) {
2349 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2350 "adapter\n", __FUNCTION__, ioc->name));
2351 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2352 ioc->cached_fw, CAN_SLEEP)) < 0) {
2353 printk(MYIOC_s_WARN_FMT
2354 ": firmware downloadboot failure (%d)!\n",
2355 ioc->name, ret);
2356 }
2357 }
2358
2359 /* Disable adapter interrupts! */
2360 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2361 ioc->active = 0;
2362 /* Clear any lingering interrupt */
2363 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2364
2365 if (ioc->alloc != NULL) {
2366 sz = ioc->alloc_sz;
2367 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2368 ioc->name, ioc->alloc, ioc->alloc_sz));
2369 pci_free_consistent(ioc->pcidev, sz,
2370 ioc->alloc, ioc->alloc_dma);
2371 ioc->reply_frames = NULL;
2372 ioc->req_frames = NULL;
2373 ioc->alloc = NULL;
2374 ioc->alloc_total -= sz;
2375 }
2376
2377 if (ioc->sense_buf_pool != NULL) {
2378 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2379 pci_free_consistent(ioc->pcidev, sz,
2380 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2381 ioc->sense_buf_pool = NULL;
2382 ioc->alloc_total -= sz;
2383 }
2384
2385 if (ioc->events != NULL){
2386 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2387 kfree(ioc->events);
2388 ioc->events = NULL;
2389 ioc->alloc_total -= sz;
2390 }
2391
2392 mpt_free_fw_memory(ioc);
2393
2394 kfree(ioc->spi_data.nvram);
2395 mpt_inactive_raid_list_free(ioc);
2396 kfree(ioc->raid_data.pIocPg2);
2397 kfree(ioc->raid_data.pIocPg3);
2398 ioc->spi_data.nvram = NULL;
2399 ioc->raid_data.pIocPg3 = NULL;
2400
2401 if (ioc->spi_data.pIocPg4 != NULL) {
2402 sz = ioc->spi_data.IocPg4Sz;
2403 pci_free_consistent(ioc->pcidev, sz,
2404 ioc->spi_data.pIocPg4,
2405 ioc->spi_data.IocPg4_dma);
2406 ioc->spi_data.pIocPg4 = NULL;
2407 ioc->alloc_total -= sz;
2408 }
2409
2410 if (ioc->ReqToChain != NULL) {
2411 kfree(ioc->ReqToChain);
2412 kfree(ioc->RequestNB);
2413 ioc->ReqToChain = NULL;
2414 }
2415
2416 kfree(ioc->ChainToChain);
2417 ioc->ChainToChain = NULL;
2418
2419 if (ioc->HostPageBuffer != NULL) {
2420 if((ret = mpt_host_page_access_control(ioc,
2421 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2422 printk(MYIOC_s_ERR_FMT
2423 "host page buffers free failed (%d)!\n",
2424 ioc->name, ret);
2425 }
2426 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2427 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2428 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2429 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2430 ioc->HostPageBuffer = NULL;
2431 ioc->HostPageBuffer_sz = 0;
2432 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2433 }
2434 }
2435
2436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2437 /**
2438 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2439 * @ioc: Pointer to MPT adapter structure
2440 *
2441 * This routine unregisters h/w resources and frees all alloc'd memory
2442 * associated with a MPT adapter structure.
2443 */
2444 static void
2445 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2446 {
2447 int sz_first, sz_last;
2448
2449 if (ioc == NULL)
2450 return;
2451
2452 sz_first = ioc->alloc_total;
2453
2454 mpt_adapter_disable(ioc);
2455
2456 if (ioc->pci_irq != -1) {
2457 free_irq(ioc->pci_irq, ioc);
2458 if (ioc->msi_enable)
2459 pci_disable_msi(ioc->pcidev);
2460 ioc->pci_irq = -1;
2461 }
2462
2463 if (ioc->memmap != NULL) {
2464 iounmap(ioc->memmap);
2465 ioc->memmap = NULL;
2466 }
2467
2468 pci_disable_device(ioc->pcidev);
2469 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2470
2471 #if defined(CONFIG_MTRR) && 0
2472 if (ioc->mtrr_reg > 0) {
2473 mtrr_del(ioc->mtrr_reg, 0, 0);
2474 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2475 }
2476 #endif
2477
2478 /* Zap the adapter lookup ptr! */
2479 list_del(&ioc->list);
2480
2481 sz_last = ioc->alloc_total;
2482 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2483 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2484
2485 if (ioc->alt_ioc)
2486 ioc->alt_ioc->alt_ioc = NULL;
2487
2488 kfree(ioc);
2489 }
2490
2491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2492 /**
2493 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2494 * @ioc: Pointer to MPT adapter structure
2495 */
2496 static void
2497 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2498 {
2499 int i = 0;
2500
2501 printk(KERN_INFO "%s: ", ioc->name);
2502 if (ioc->prod_name)
2503 printk("%s: ", ioc->prod_name);
2504 printk("Capabilities={");
2505
2506 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2507 printk("Initiator");
2508 i++;
2509 }
2510
2511 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2512 printk("%sTarget", i ? "," : "");
2513 i++;
2514 }
2515
2516 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2517 printk("%sLAN", i ? "," : "");
2518 i++;
2519 }
2520
2521 #if 0
2522 /*
2523 * This would probably evoke more questions than it's worth
2524 */
2525 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2526 printk("%sLogBusAddr", i ? "," : "");
2527 i++;
2528 }
2529 #endif
2530
2531 printk("}\n");
2532 }
2533
2534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2535 /**
2536 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2537 * @ioc: Pointer to MPT_ADAPTER structure
2538 * @force: Force hard KickStart of IOC
2539 * @sleepFlag: Specifies whether the process can sleep
2540 *
2541 * Returns:
2542 * 1 - DIAG reset and READY
2543 * 0 - READY initially OR soft reset and READY
2544 * -1 - Any failure on KickStart
2545 * -2 - Msg Unit Reset Failed
2546 * -3 - IO Unit Reset Failed
2547 * -4 - IOC owned by a PEER
2548 */
2549 static int
2550 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2551 {
2552 u32 ioc_state;
2553 int statefault = 0;
2554 int cntdn;
2555 int hard_reset_done = 0;
2556 int r;
2557 int ii;
2558 int whoinit;
2559
2560 /* Get current [raw] IOC state */
2561 ioc_state = mpt_GetIocState(ioc, 0);
2562 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2563
2564 /*
2565 * Check to see if IOC got left/stuck in doorbell handshake
2566 * grip of death. If so, hard reset the IOC.
2567 */
2568 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2569 statefault = 1;
2570 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2571 ioc->name);
2572 }
2573
2574 /* Is it already READY? */
2575 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2576 return 0;
2577
2578 /*
2579 * Check to see if IOC is in FAULT state.
2580 */
2581 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2582 statefault = 2;
2583 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2584 ioc->name);
2585 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2586 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2587 }
2588
2589 /*
2590 * Hmmm... Did it get left operational?
2591 */
2592 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2593 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2594 ioc->name));
2595
2596 /* Check WhoInit.
2597 * If PCI Peer, exit.
2598 * Else, if no fault conditions are present, issue a MessageUnitReset
2599 * Else, fall through to KickStart case
2600 */
2601 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2602 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2603 "whoinit 0x%x statefault %d force %d\n",
2604 ioc->name, whoinit, statefault, force));
2605 if (whoinit == MPI_WHOINIT_PCI_PEER)
2606 return -4;
2607 else {
2608 if ((statefault == 0 ) && (force == 0)) {
2609 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2610 return 0;
2611 }
2612 statefault = 3;
2613 }
2614 }
2615
2616 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2617 if (hard_reset_done < 0)
2618 return -1;
2619
2620 /*
2621 * Loop here waiting for IOC to come READY.
2622 */
2623 ii = 0;
2624 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2625
2626 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2627 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2628 /*
2629 * BIOS or previous driver load left IOC in OP state.
2630 * Reset messaging FIFOs.
2631 */
2632 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2633 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2634 return -2;
2635 }
2636 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2637 /*
2638 * Something is wrong. Try to get IOC back
2639 * to a known state.
2640 */
2641 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2642 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2643 return -3;
2644 }
2645 }
2646
2647 ii++; cntdn--;
2648 if (!cntdn) {
2649 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2650 ioc->name, (int)((ii+5)/HZ));
2651 return -ETIME;
2652 }
2653
2654 if (sleepFlag == CAN_SLEEP) {
2655 msleep(1);
2656 } else {
2657 mdelay (1); /* 1 msec delay */
2658 }
2659
2660 }
2661
2662 if (statefault < 3) {
2663 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2664 ioc->name,
2665 statefault==1 ? "stuck handshake" : "IOC FAULT");
2666 }
2667
2668 return hard_reset_done;
2669 }
2670
2671 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2672 /**
2673 * mpt_GetIocState - Get the current state of a MPT adapter.
2674 * @ioc: Pointer to MPT_ADAPTER structure
2675 * @cooked: Request raw or cooked IOC state
2676 *
2677 * Returns all IOC Doorbell register bits if cooked==0, else just the
2678 * Doorbell bits in MPI_IOC_STATE_MASK.
2679 */
2680 u32
2681 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2682 {
2683 u32 s, sc;
2684
2685 /* Get! */
2686 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2687 sc = s & MPI_IOC_STATE_MASK;
2688
2689 /* Save! */
2690 ioc->last_state = sc;
2691
2692 return cooked ? sc : s;
2693 }
2694
2695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2696 /**
2697 * GetIocFacts - Send IOCFacts request to MPT adapter.
2698 * @ioc: Pointer to MPT_ADAPTER structure
2699 * @sleepFlag: Specifies whether the process can sleep
2700 * @reason: If recovery, only update facts.
2701 *
2702 * Returns 0 for success, non-zero for failure.
2703 */
2704 static int
2705 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2706 {
2707 IOCFacts_t get_facts;
2708 IOCFactsReply_t *facts;
2709 int r;
2710 int req_sz;
2711 int reply_sz;
2712 int sz;
2713 u32 status, vv;
2714 u8 shiftFactor=1;
2715
2716 /* IOC *must* NOT be in RESET state! */
2717 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2718 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2719 ioc->name, ioc->last_state );
2720 return -44;
2721 }
2722
2723 facts = &ioc->facts;
2724
2725 /* Destination (reply area)... */
2726 reply_sz = sizeof(*facts);
2727 memset(facts, 0, reply_sz);
2728
2729 /* Request area (get_facts on the stack right now!) */
2730 req_sz = sizeof(get_facts);
2731 memset(&get_facts, 0, req_sz);
2732
2733 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2734 /* Assert: All other get_facts fields are zero! */
2735
2736 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2737 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2738 ioc->name, req_sz, reply_sz));
2739
2740 /* No non-zero fields in the get_facts request are greater than
2741 * 1 byte in size, so we can just fire it off as is.
2742 */
2743 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2744 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2745 if (r != 0)
2746 return r;
2747
2748 /*
2749 * Now byte swap (GRRR) the necessary fields before any further
2750 * inspection of reply contents.
2751 *
2752 * But need to do some sanity checks on MsgLength (byte) field
2753 * to make sure we don't zero IOC's req_sz!
2754 */
2755 /* Did we get a valid reply? */
2756 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2757 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2758 /*
2759 * If not been here, done that, save off first WhoInit value
2760 */
2761 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2762 ioc->FirstWhoInit = facts->WhoInit;
2763 }
2764
2765 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2766 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2767 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2768 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2769 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2770 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2771 /* CHECKME! IOCStatus, IOCLogInfo */
2772
2773 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2774 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2775
2776 /*
2777 * FC f/w version changed between 1.1 and 1.2
2778 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2779 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2780 */
2781 if (facts->MsgVersion < 0x0102) {
2782 /*
2783 * Handle old FC f/w style, convert to new...
2784 */
2785 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2786 facts->FWVersion.Word =
2787 ((oldv<<12) & 0xFF000000) |
2788 ((oldv<<8) & 0x000FFF00);
2789 } else
2790 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2791
2792 facts->ProductID = le16_to_cpu(facts->ProductID);
2793 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2794 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2795 ioc->ir_firmware = 1;
2796 facts->CurrentHostMfaHighAddr =
2797 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2798 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2799 facts->CurrentSenseBufferHighAddr =
2800 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2801 facts->CurReplyFrameSize =
2802 le16_to_cpu(facts->CurReplyFrameSize);
2803 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2804
2805 /*
2806 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2807 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2808 * to 14 in MPI-1.01.0x.
2809 */
2810 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2811 facts->MsgVersion > 0x0100) {
2812 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2813 }
2814
2815 sz = facts->FWImageSize;
2816 if ( sz & 0x01 )
2817 sz += 1;
2818 if ( sz & 0x02 )
2819 sz += 2;
2820 facts->FWImageSize = sz;
2821
2822 if (!facts->RequestFrameSize) {
2823 /* Something is wrong! */
2824 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2825 ioc->name);
2826 return -55;
2827 }
2828
2829 r = sz = facts->BlockSize;
2830 vv = ((63 / (sz * 4)) + 1) & 0x03;
2831 ioc->NB_for_64_byte_frame = vv;
2832 while ( sz )
2833 {
2834 shiftFactor++;
2835 sz = sz >> 1;
2836 }
2837 ioc->NBShiftFactor = shiftFactor;
2838 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2839 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2840 ioc->name, vv, shiftFactor, r));
2841
2842 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2843 /*
2844 * Set values for this IOC's request & reply frame sizes,
2845 * and request & reply queue depths...
2846 */
2847 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2848 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2849 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2850 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2851
2852 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2853 ioc->name, ioc->reply_sz, ioc->reply_depth));
2854 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2855 ioc->name, ioc->req_sz, ioc->req_depth));
2856
2857 /* Get port facts! */
2858 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2859 return r;
2860 }
2861 } else {
2862 printk(MYIOC_s_ERR_FMT
2863 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2864 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2865 RequestFrameSize)/sizeof(u32)));
2866 return -66;
2867 }
2868
2869 return 0;
2870 }
2871
2872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2873 /**
2874 * GetPortFacts - Send PortFacts request to MPT adapter.
2875 * @ioc: Pointer to MPT_ADAPTER structure
2876 * @portnum: Port number
2877 * @sleepFlag: Specifies whether the process can sleep
2878 *
2879 * Returns 0 for success, non-zero for failure.
2880 */
2881 static int
2882 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2883 {
2884 PortFacts_t get_pfacts;
2885 PortFactsReply_t *pfacts;
2886 int ii;
2887 int req_sz;
2888 int reply_sz;
2889 int max_id;
2890
2891 /* IOC *must* NOT be in RESET state! */
2892 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2893 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2894 ioc->name, ioc->last_state );
2895 return -4;
2896 }
2897
2898 pfacts = &ioc->pfacts[portnum];
2899
2900 /* Destination (reply area)... */
2901 reply_sz = sizeof(*pfacts);
2902 memset(pfacts, 0, reply_sz);
2903
2904 /* Request area (get_pfacts on the stack right now!) */
2905 req_sz = sizeof(get_pfacts);
2906 memset(&get_pfacts, 0, req_sz);
2907
2908 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2909 get_pfacts.PortNumber = portnum;
2910 /* Assert: All other get_pfacts fields are zero! */
2911
2912 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2913 ioc->name, portnum));
2914
2915 /* No non-zero fields in the get_pfacts request are greater than
2916 * 1 byte in size, so we can just fire it off as is.
2917 */
2918 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2919 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2920 if (ii != 0)
2921 return ii;
2922
2923 /* Did we get a valid reply? */
2924
2925 /* Now byte swap the necessary fields in the response. */
2926 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2927 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2928 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2929 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2930 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2931 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2932 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2933 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2934 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2935
2936 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2937 pfacts->MaxDevices;
2938 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2939 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2940
2941 /*
2942 * Place all the devices on channels
2943 *
2944 * (for debuging)
2945 */
2946 if (mpt_channel_mapping) {
2947 ioc->devices_per_bus = 1;
2948 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2949 }
2950
2951 return 0;
2952 }
2953
2954 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2955 /**
2956 * SendIocInit - Send IOCInit request to MPT adapter.
2957 * @ioc: Pointer to MPT_ADAPTER structure
2958 * @sleepFlag: Specifies whether the process can sleep
2959 *
2960 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2961 *
2962 * Returns 0 for success, non-zero for failure.
2963 */
2964 static int
2965 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2966 {
2967 IOCInit_t ioc_init;
2968 MPIDefaultReply_t init_reply;
2969 u32 state;
2970 int r;
2971 int count;
2972 int cntdn;
2973
2974 memset(&ioc_init, 0, sizeof(ioc_init));
2975 memset(&init_reply, 0, sizeof(init_reply));
2976
2977 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2978 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2979
2980 /* If we are in a recovery mode and we uploaded the FW image,
2981 * then this pointer is not NULL. Skip the upload a second time.
2982 * Set this flag if cached_fw set for either IOC.
2983 */
2984 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2985 ioc->upload_fw = 1;
2986 else
2987 ioc->upload_fw = 0;
2988 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2989 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2990
2991 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2992 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2993 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2994 ioc->name, ioc->facts.MsgVersion));
2995 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2996 // set MsgVersion and HeaderVersion host driver was built with
2997 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2998 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2999
3000 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3001 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3002 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3003 return -99;
3004 }
3005 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3006
3007 if (sizeof(dma_addr_t) == sizeof(u64)) {
3008 /* Save the upper 32-bits of the request
3009 * (reply) and sense buffers.
3010 */
3011 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3012 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3013 } else {
3014 /* Force 32-bit addressing */
3015 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3016 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3017 }
3018
3019 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3020 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3021 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3022 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3023
3024 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3025 ioc->name, &ioc_init));
3026
3027 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3028 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3029 if (r != 0) {
3030 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3031 return r;
3032 }
3033
3034 /* No need to byte swap the multibyte fields in the reply
3035 * since we don't even look at its contents.
3036 */
3037
3038 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3039 ioc->name, &ioc_init));
3040
3041 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3042 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3043 return r;
3044 }
3045
3046 /* YIKES! SUPER IMPORTANT!!!
3047 * Poll IocState until _OPERATIONAL while IOC is doing
3048 * LoopInit and TargetDiscovery!
3049 */
3050 count = 0;
3051 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3052 state = mpt_GetIocState(ioc, 1);
3053 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3054 if (sleepFlag == CAN_SLEEP) {
3055 msleep(1);
3056 } else {
3057 mdelay(1);
3058 }
3059
3060 if (!cntdn) {
3061 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3062 ioc->name, (int)((count+5)/HZ));
3063 return -9;
3064 }
3065
3066 state = mpt_GetIocState(ioc, 1);
3067 count++;
3068 }
3069 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3070 ioc->name, count));
3071
3072 ioc->aen_event_read_flag=0;
3073 return r;
3074 }
3075
3076 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3077 /**
3078 * SendPortEnable - Send PortEnable request to MPT adapter port.
3079 * @ioc: Pointer to MPT_ADAPTER structure
3080 * @portnum: Port number to enable
3081 * @sleepFlag: Specifies whether the process can sleep
3082 *
3083 * Send PortEnable to bring IOC to OPERATIONAL state.
3084 *
3085 * Returns 0 for success, non-zero for failure.
3086 */
3087 static int
3088 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3089 {
3090 PortEnable_t port_enable;
3091 MPIDefaultReply_t reply_buf;
3092 int rc;
3093 int req_sz;
3094 int reply_sz;
3095
3096 /* Destination... */
3097 reply_sz = sizeof(MPIDefaultReply_t);
3098 memset(&reply_buf, 0, reply_sz);
3099
3100 req_sz = sizeof(PortEnable_t);
3101 memset(&port_enable, 0, req_sz);
3102
3103 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3104 port_enable.PortNumber = portnum;
3105 /* port_enable.ChainOffset = 0; */
3106 /* port_enable.MsgFlags = 0; */
3107 /* port_enable.MsgContext = 0; */
3108
3109 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3110 ioc->name, portnum, &port_enable));
3111
3112 /* RAID FW may take a long time to enable
3113 */
3114 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3115 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3116 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3117 300 /*seconds*/, sleepFlag);
3118 } else {
3119 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3120 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3121 30 /*seconds*/, sleepFlag);
3122 }
3123 return rc;
3124 }
3125
3126 /**
3127 * mpt_alloc_fw_memory - allocate firmware memory
3128 * @ioc: Pointer to MPT_ADAPTER structure
3129 * @size: total FW bytes
3130 *
3131 * If memory has already been allocated, the same (cached) value
3132 * is returned.
3133 *
3134 * Return 0 if successfull, or non-zero for failure
3135 **/
3136 int
3137 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3138 {
3139 int rc;
3140
3141 if (ioc->cached_fw) {
3142 rc = 0; /* use already allocated memory */
3143 goto out;
3144 }
3145 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3146 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3147 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3148 rc = 0;
3149 goto out;
3150 }
3151 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3152 if (!ioc->cached_fw) {
3153 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3154 ioc->name);
3155 rc = -1;
3156 } else {
3157 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3158 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3159 ioc->alloc_total += size;
3160 rc = 0;
3161 }
3162 out:
3163 return rc;
3164 }
3165
3166 /**
3167 * mpt_free_fw_memory - free firmware memory
3168 * @ioc: Pointer to MPT_ADAPTER structure
3169 *
3170 * If alt_img is NULL, delete from ioc structure.
3171 * Else, delete a secondary image in same format.
3172 **/
3173 void
3174 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3175 {
3176 int sz;
3177
3178 if (!ioc->cached_fw)
3179 return;
3180
3181 sz = ioc->facts.FWImageSize;
3182 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3183 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3184 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3185 ioc->alloc_total -= sz;
3186 ioc->cached_fw = NULL;
3187 }
3188
3189 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3190 /**
3191 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3192 * @ioc: Pointer to MPT_ADAPTER structure
3193 * @sleepFlag: Specifies whether the process can sleep
3194 *
3195 * Returns 0 for success, >0 for handshake failure
3196 * <0 for fw upload failure.
3197 *
3198 * Remark: If bound IOC and a successful FWUpload was performed
3199 * on the bound IOC, the second image is discarded
3200 * and memory is free'd. Both channels must upload to prevent
3201 * IOC from running in degraded mode.
3202 */
3203 static int
3204 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3205 {
3206 u8 reply[sizeof(FWUploadReply_t)];
3207 FWUpload_t *prequest;
3208 FWUploadReply_t *preply;
3209 FWUploadTCSGE_t *ptcsge;
3210 int sgeoffset;
3211 u32 flagsLength;
3212 int ii, sz, reply_sz;
3213 int cmdStatus;
3214
3215 /* If the image size is 0, we are done.
3216 */
3217 if ((sz = ioc->facts.FWImageSize) == 0)
3218 return 0;
3219
3220 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3221 return -ENOMEM;
3222
3223 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3224 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3225
3226 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3227 kzalloc(ioc->req_sz, GFP_KERNEL);
3228 if (!prequest) {
3229 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3230 "while allocating memory \n", ioc->name));
3231 mpt_free_fw_memory(ioc);
3232 return -ENOMEM;
3233 }
3234
3235 preply = (FWUploadReply_t *)&reply;
3236
3237 reply_sz = sizeof(reply);
3238 memset(preply, 0, reply_sz);
3239
3240 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3241 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3242
3243 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3244 ptcsge->DetailsLength = 12;
3245 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3246 ptcsge->ImageSize = cpu_to_le32(sz);
3247 ptcsge++;
3248
3249 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3250
3251 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3252 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3253
3254 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3255 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3256 ioc->name, prequest, sgeoffset));
3257 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3258
3259 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3260 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3261
3262 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3263
3264 cmdStatus = -EFAULT;
3265 if (ii == 0) {
3266 /* Handshake transfer was complete and successful.
3267 * Check the Reply Frame.
3268 */
3269 int status, transfer_sz;
3270 status = le16_to_cpu(preply->IOCStatus);
3271 if (status == MPI_IOCSTATUS_SUCCESS) {
3272 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3273 if (transfer_sz == sz)
3274 cmdStatus = 0;
3275 }
3276 }
3277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3278 ioc->name, cmdStatus));
3279
3280
3281 if (cmdStatus) {
3282
3283 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3284 ioc->name));
3285 mpt_free_fw_memory(ioc);
3286 }
3287 kfree(prequest);
3288
3289 return cmdStatus;
3290 }
3291
3292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3293 /**
3294 * mpt_downloadboot - DownloadBoot code
3295 * @ioc: Pointer to MPT_ADAPTER structure
3296 * @pFwHeader: Pointer to firmware header info
3297 * @sleepFlag: Specifies whether the process can sleep
3298 *
3299 * FwDownloadBoot requires Programmed IO access.
3300 *
3301 * Returns 0 for success
3302 * -1 FW Image size is 0
3303 * -2 No valid cached_fw Pointer
3304 * <0 for fw upload failure.
3305 */
3306 static int
3307 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3308 {
3309 MpiExtImageHeader_t *pExtImage;
3310 u32 fwSize;
3311 u32 diag0val;
3312 int count;
3313 u32 *ptrFw;
3314 u32 diagRwData;
3315 u32 nextImage;
3316 u32 load_addr;
3317 u32 ioc_state=0;
3318
3319 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3320 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3321
3322 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3323 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3324 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3325 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3326 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3327 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3328
3329 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3330
3331 /* wait 1 msec */
3332 if (sleepFlag == CAN_SLEEP) {
3333 msleep(1);
3334 } else {
3335 mdelay (1);
3336 }
3337
3338 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3339 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3340
3341 for (count = 0; count < 30; count ++) {
3342 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3343 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3344 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3345 ioc->name, count));
3346 break;
3347 }
3348 /* wait .1 sec */
3349 if (sleepFlag == CAN_SLEEP) {
3350 msleep (100);
3351 } else {
3352 mdelay (100);
3353 }
3354 }
3355
3356 if ( count == 30 ) {
3357 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3358 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3359 ioc->name, diag0val));
3360 return -3;
3361 }
3362
3363 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3364 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3365 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3366 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3367 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3368 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3369
3370 /* Set the DiagRwEn and Disable ARM bits */
3371 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3372
3373 fwSize = (pFwHeader->ImageSize + 3)/4;
3374 ptrFw = (u32 *) pFwHeader;
3375
3376 /* Write the LoadStartAddress to the DiagRw Address Register
3377 * using Programmed IO
3378 */
3379 if (ioc->errata_flag_1064)
3380 pci_enable_io_access(ioc->pcidev);
3381
3382 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3383 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3384 ioc->name, pFwHeader->LoadStartAddress));
3385
3386 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3387 ioc->name, fwSize*4, ptrFw));
3388 while (fwSize--) {
3389 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3390 }
3391
3392 nextImage = pFwHeader->NextImageHeaderOffset;
3393 while (nextImage) {
3394 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3395
3396 load_addr = pExtImage->LoadStartAddress;
3397
3398 fwSize = (pExtImage->ImageSize + 3) >> 2;
3399 ptrFw = (u32 *)pExtImage;
3400
3401 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3402 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3403 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3404
3405 while (fwSize--) {
3406 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3407 }
3408 nextImage = pExtImage->NextImageHeaderOffset;
3409 }
3410
3411 /* Write the IopResetVectorRegAddr */
3412 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3413 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3414
3415 /* Write the IopResetVectorValue */
3416 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3417 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3418
3419 /* Clear the internal flash bad bit - autoincrementing register,
3420 * so must do two writes.
3421 */
3422 if (ioc->bus_type == SPI) {
3423 /*
3424 * 1030 and 1035 H/W errata, workaround to access
3425 * the ClearFlashBadSignatureBit
3426 */
3427 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3428 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3429 diagRwData |= 0x40000000;
3430 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3431 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3432
3433 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3434 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3435 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3436 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3437
3438 /* wait 1 msec */
3439 if (sleepFlag == CAN_SLEEP) {
3440 msleep (1);
3441 } else {
3442 mdelay (1);
3443 }
3444 }
3445
3446 if (ioc->errata_flag_1064)
3447 pci_disable_io_access(ioc->pcidev);
3448
3449 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3450 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3451 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3452 ioc->name, diag0val));
3453 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3454 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3455 ioc->name, diag0val));
3456 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3457
3458 /* Write 0xFF to reset the sequencer */
3459 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3460
3461 if (ioc->bus_type == SAS) {
3462 ioc_state = mpt_GetIocState(ioc, 0);
3463 if ( (GetIocFacts(ioc, sleepFlag,
3464 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3465 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3466 ioc->name, ioc_state));
3467 return -EFAULT;
3468 }
3469 }
3470
3471 for (count=0; count<HZ*20; count++) {
3472 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3473 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3474 "downloadboot successful! (count=%d) IocState=%x\n",
3475 ioc->name, count, ioc_state));
3476 if (ioc->bus_type == SAS) {
3477 return 0;
3478 }
3479 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3480 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3481 "downloadboot: SendIocInit failed\n",
3482 ioc->name));
3483 return -EFAULT;
3484 }
3485 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3486 "downloadboot: SendIocInit successful\n",
3487 ioc->name));
3488 return 0;
3489 }
3490 if (sleepFlag == CAN_SLEEP) {
3491 msleep (10);
3492 } else {
3493 mdelay (10);
3494 }
3495 }
3496 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3497 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3498 return -EFAULT;
3499 }
3500
3501 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3502 /**
3503 * KickStart - Perform hard reset of MPT adapter.
3504 * @ioc: Pointer to MPT_ADAPTER structure
3505 * @force: Force hard reset
3506 * @sleepFlag: Specifies whether the process can sleep
3507 *
3508 * This routine places MPT adapter in diagnostic mode via the
3509 * WriteSequence register, and then performs a hard reset of adapter
3510 * via the Diagnostic register.
3511 *
3512 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3513 * or NO_SLEEP (interrupt thread, use mdelay)
3514 * force - 1 if doorbell active, board fault state
3515 * board operational, IOC_RECOVERY or
3516 * IOC_BRINGUP and there is an alt_ioc.
3517 * 0 else
3518 *
3519 * Returns:
3520 * 1 - hard reset, READY
3521 * 0 - no reset due to History bit, READY
3522 * -1 - no reset due to History bit but not READY
3523 * OR reset but failed to come READY
3524 * -2 - no reset, could not enter DIAG mode
3525 * -3 - reset but bad FW bit
3526 */
3527 static int
3528 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3529 {
3530 int hard_reset_done = 0;
3531 u32 ioc_state=0;
3532 int cnt,cntdn;
3533
3534 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3535 if (ioc->bus_type == SPI) {
3536 /* Always issue a Msg Unit Reset first. This will clear some
3537 * SCSI bus hang conditions.
3538 */
3539 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3540
3541 if (sleepFlag == CAN_SLEEP) {
3542 msleep (1000);
3543 } else {
3544 mdelay (1000);
3545 }
3546 }
3547
3548 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3549 if (hard_reset_done < 0)
3550 return hard_reset_done;
3551
3552 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3553 ioc->name));
3554
3555 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3556 for (cnt=0; cnt<cntdn; cnt++) {
3557 ioc_state = mpt_GetIocState(ioc, 1);
3558 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3559 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3560 ioc->name, cnt));
3561 return hard_reset_done;
3562 }
3563 if (sleepFlag == CAN_SLEEP) {
3564 msleep (10);
3565 } else {
3566 mdelay (10);
3567 }
3568 }
3569
3570 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3571 ioc->name, mpt_GetIocState(ioc, 0)));
3572 return -1;
3573 }
3574
3575 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3576 /**
3577 * mpt_diag_reset - Perform hard reset of the adapter.
3578 * @ioc: Pointer to MPT_ADAPTER structure
3579 * @ignore: Set if to honor and clear to ignore
3580 * the reset history bit
3581 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3582 * else set to NO_SLEEP (use mdelay instead)
3583 *
3584 * This routine places the adapter in diagnostic mode via the
3585 * WriteSequence register and then performs a hard reset of adapter
3586 * via the Diagnostic register. Adapter should be in ready state
3587 * upon successful completion.
3588 *
3589 * Returns: 1 hard reset successful
3590 * 0 no reset performed because reset history bit set
3591 * -2 enabling diagnostic mode failed
3592 * -3 diagnostic reset failed
3593 */
3594 static int
3595 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3596 {
3597 u32 diag0val;
3598 u32 doorbell;
3599 int hard_reset_done = 0;
3600 int count = 0;
3601 u32 diag1val = 0;
3602 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3603
3604 /* Clear any existing interrupts */
3605 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3606
3607 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3608 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3609 "address=%p\n", ioc->name, __FUNCTION__,
3610 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3611 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3612 if (sleepFlag == CAN_SLEEP)
3613 msleep(1);
3614 else
3615 mdelay(1);
3616
3617 for (count = 0; count < 60; count ++) {
3618 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3619 doorbell &= MPI_IOC_STATE_MASK;
3620
3621 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3622 "looking for READY STATE: doorbell=%x"
3623 " count=%d\n",
3624 ioc->name, doorbell, count));
3625 if (doorbell == MPI_IOC_STATE_READY) {
3626 return 1;
3627 }
3628
3629 /* wait 1 sec */
3630 if (sleepFlag == CAN_SLEEP)
3631 msleep(1000);
3632 else
3633 mdelay(1000);
3634 }
3635 return -1;
3636 }
3637
3638 /* Use "Diagnostic reset" method! (only thing available!) */
3639 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3640
3641 if (ioc->debug_level & MPT_DEBUG) {
3642 if (ioc->alt_ioc)
3643 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3644 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3645 ioc->name, diag0val, diag1val));
3646 }
3647
3648 /* Do the reset if we are told to ignore the reset history
3649 * or if the reset history is 0
3650 */
3651 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3652 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3653 /* Write magic sequence to WriteSequence register
3654 * Loop until in diagnostic mode
3655 */
3656 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3657 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3658 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3659 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3660 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3661 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3662
3663 /* wait 100 msec */
3664 if (sleepFlag == CAN_SLEEP) {
3665 msleep (100);
3666 } else {
3667 mdelay (100);
3668 }
3669
3670 count++;
3671 if (count > 20) {
3672 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3673 ioc->name, diag0val);
3674 return -2;
3675
3676 }
3677
3678 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3679
3680 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3681 ioc->name, diag0val));
3682 }
3683
3684 if (ioc->debug_level & MPT_DEBUG) {
3685 if (ioc->alt_ioc)
3686 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3687 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3688 ioc->name, diag0val, diag1val));
3689 }
3690 /*
3691 * Disable the ARM (Bug fix)
3692 *
3693 */
3694 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3695 mdelay(1);
3696
3697 /*
3698 * Now hit the reset bit in the Diagnostic register
3699 * (THE BIG HAMMER!) (Clears DRWE bit).
3700 */
3701 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3702 hard_reset_done = 1;
3703 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3704 ioc->name));
3705
3706 /*
3707 * Call each currently registered protocol IOC reset handler
3708 * with pre-reset indication.
3709 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3710 * MptResetHandlers[] registered yet.
3711 */
3712 {
3713 u8 cb_idx;
3714 int r = 0;
3715
3716 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3717 if (MptResetHandlers[cb_idx]) {
3718 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3719 "Calling IOC pre_reset handler #%d\n",
3720 ioc->name, cb_idx));
3721 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3722 if (ioc->alt_ioc) {
3723 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3724 "Calling alt-%s pre_reset handler #%d\n",
3725 ioc->name, ioc->alt_ioc->name, cb_idx));
3726 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3727 }
3728 }
3729 }
3730 /* FIXME? Examine results here? */
3731 }
3732
3733 if (ioc->cached_fw)
3734 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3735 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3736 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3737 else
3738 cached_fw = NULL;
3739 if (cached_fw) {
3740 /* If the DownloadBoot operation fails, the
3741 * IOC will be left unusable. This is a fatal error
3742 * case. _diag_reset will return < 0
3743 */
3744 for (count = 0; count < 30; count ++) {
3745 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3746 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3747 break;
3748 }
3749
3750 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3751 ioc->name, diag0val, count));
3752 /* wait 1 sec */
3753 if (sleepFlag == CAN_SLEEP) {
3754 msleep (1000);
3755 } else {
3756 mdelay (1000);
3757 }
3758 }
3759 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3760 printk(MYIOC_s_WARN_FMT
3761 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3762 }
3763
3764 } else {
3765 /* Wait for FW to reload and for board
3766 * to go to the READY state.
3767 * Maximum wait is 60 seconds.
3768 * If fail, no error will check again
3769 * with calling program.
3770 */
3771 for (count = 0; count < 60; count ++) {
3772 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3773 doorbell &= MPI_IOC_STATE_MASK;
3774
3775 if (doorbell == MPI_IOC_STATE_READY) {
3776 break;
3777 }
3778
3779 /* wait 1 sec */
3780 if (sleepFlag == CAN_SLEEP) {
3781 msleep (1000);
3782 } else {
3783 mdelay (1000);
3784 }
3785 }
3786 }
3787 }
3788
3789 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3790 if (ioc->debug_level & MPT_DEBUG) {
3791 if (ioc->alt_ioc)
3792 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3793 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3794 ioc->name, diag0val, diag1val));
3795 }
3796
3797 /* Clear RESET_HISTORY bit! Place board in the
3798 * diagnostic mode to update the diag register.
3799 */
3800 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3801 count = 0;
3802 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3803 /* Write magic sequence to WriteSequence register
3804 * Loop until in diagnostic mode
3805 */
3806 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3807 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3808 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3809 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3810 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3811 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3812
3813 /* wait 100 msec */
3814 if (sleepFlag == CAN_SLEEP) {
3815 msleep (100);
3816 } else {
3817 mdelay (100);
3818 }
3819
3820 count++;
3821 if (count > 20) {
3822 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3823 ioc->name, diag0val);
3824 break;
3825 }
3826 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3827 }
3828 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3829 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3830 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3831 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3832 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3833 ioc->name);
3834 }
3835
3836 /* Disable Diagnostic Mode
3837 */
3838 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3839
3840 /* Check FW reload status flags.
3841 */
3842 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3843 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3844 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3845 ioc->name, diag0val);
3846 return -3;
3847 }
3848
3849 if (ioc->debug_level & MPT_DEBUG) {
3850 if (ioc->alt_ioc)
3851 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3852 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3853 ioc->name, diag0val, diag1val));
3854 }
3855
3856 /*
3857 * Reset flag that says we've enabled event notification
3858 */
3859 ioc->facts.EventState = 0;
3860
3861 if (ioc->alt_ioc)
3862 ioc->alt_ioc->facts.EventState = 0;
3863
3864 return hard_reset_done;
3865 }
3866
3867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3868 /**
3869 * SendIocReset - Send IOCReset request to MPT adapter.
3870 * @ioc: Pointer to MPT_ADAPTER structure
3871 * @reset_type: reset type, expected values are
3872 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3873 * @sleepFlag: Specifies whether the process can sleep
3874 *
3875 * Send IOCReset request to the MPT adapter.
3876 *
3877 * Returns 0 for success, non-zero for failure.
3878 */
3879 static int
3880 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3881 {
3882 int r;
3883 u32 state;
3884 int cntdn, count;
3885
3886 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3887 ioc->name, reset_type));
3888 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3889 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3890 return r;
3891
3892 /* FW ACK'd request, wait for READY state
3893 */
3894 count = 0;
3895 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3896
3897 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3898 cntdn--;
3899 count++;
3900 if (!cntdn) {
3901 if (sleepFlag != CAN_SLEEP)
3902 count *= 10;
3903
3904 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3905 ioc->name, (int)((count+5)/HZ));
3906 return -ETIME;
3907 }
3908
3909 if (sleepFlag == CAN_SLEEP) {
3910 msleep(1);
3911 } else {
3912 mdelay (1); /* 1 msec delay */
3913 }
3914 }
3915
3916 /* TODO!
3917 * Cleanup all event stuff for this IOC; re-issue EventNotification
3918 * request if needed.
3919 */
3920 if (ioc->facts.Function)
3921 ioc->facts.EventState = 0;
3922
3923 return 0;
3924 }
3925
3926 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3927 /**
3928 * initChainBuffers - Allocate memory for and initialize chain buffers
3929 * @ioc: Pointer to MPT_ADAPTER structure
3930 *
3931 * Allocates memory for and initializes chain buffers,
3932 * chain buffer control arrays and spinlock.
3933 */
3934 static int
3935 initChainBuffers(MPT_ADAPTER *ioc)
3936 {
3937 u8 *mem;
3938 int sz, ii, num_chain;
3939 int scale, num_sge, numSGE;
3940
3941 /* ReqToChain size must equal the req_depth
3942 * index = req_idx
3943 */
3944 if (ioc->ReqToChain == NULL) {
3945 sz = ioc->req_depth * sizeof(int);
3946 mem = kmalloc(sz, GFP_ATOMIC);
3947 if (mem == NULL)
3948 return -1;
3949
3950 ioc->ReqToChain = (int *) mem;
3951 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3952 ioc->name, mem, sz));
3953 mem = kmalloc(sz, GFP_ATOMIC);
3954 if (mem == NULL)
3955 return -1;
3956
3957 ioc->RequestNB = (int *) mem;
3958 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3959 ioc->name, mem, sz));
3960 }
3961 for (ii = 0; ii < ioc->req_depth; ii++) {
3962 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3963 }
3964
3965 /* ChainToChain size must equal the total number
3966 * of chain buffers to be allocated.
3967 * index = chain_idx
3968 *
3969 * Calculate the number of chain buffers needed(plus 1) per I/O
3970 * then multiply the maximum number of simultaneous cmds
3971 *
3972 * num_sge = num sge in request frame + last chain buffer
3973 * scale = num sge per chain buffer if no chain element
3974 */
3975 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3976 if (sizeof(dma_addr_t) == sizeof(u64))
3977 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3978 else
3979 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3980
3981 if (sizeof(dma_addr_t) == sizeof(u64)) {
3982 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3983 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3984 } else {
3985 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3986 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3987 }
3988 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3989 ioc->name, num_sge, numSGE));
3990
3991 if ( numSGE > MPT_SCSI_SG_DEPTH )
3992 numSGE = MPT_SCSI_SG_DEPTH;
3993
3994 num_chain = 1;
3995 while (numSGE - num_sge > 0) {
3996 num_chain++;
3997 num_sge += (scale - 1);
3998 }
3999 num_chain++;
4000
4001 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4002 ioc->name, numSGE, num_sge, num_chain));
4003
4004 if (ioc->bus_type == SPI)
4005 num_chain *= MPT_SCSI_CAN_QUEUE;
4006 else
4007 num_chain *= MPT_FC_CAN_QUEUE;
4008
4009 ioc->num_chain = num_chain;
4010
4011 sz = num_chain * sizeof(int);
4012 if (ioc->ChainToChain == NULL) {
4013 mem = kmalloc(sz, GFP_ATOMIC);
4014 if (mem == NULL)
4015 return -1;
4016
4017 ioc->ChainToChain = (int *) mem;
4018 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4019 ioc->name, mem, sz));
4020 } else {
4021 mem = (u8 *) ioc->ChainToChain;
4022 }
4023 memset(mem, 0xFF, sz);
4024 return num_chain;
4025 }
4026
4027 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4028 /**
4029 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4030 * @ioc: Pointer to MPT_ADAPTER structure
4031 *
4032 * This routine allocates memory for the MPT reply and request frame
4033 * pools (if necessary), and primes the IOC reply FIFO with
4034 * reply frames.
4035 *
4036 * Returns 0 for success, non-zero for failure.
4037 */
4038 static int
4039 PrimeIocFifos(MPT_ADAPTER *ioc)
4040 {
4041 MPT_FRAME_HDR *mf;
4042 unsigned long flags;
4043 dma_addr_t alloc_dma;
4044 u8 *mem;
4045 int i, reply_sz, sz, total_size, num_chain;
4046
4047 /* Prime reply FIFO... */
4048
4049 if (ioc->reply_frames == NULL) {
4050 if ( (num_chain = initChainBuffers(ioc)) < 0)
4051 return -1;
4052
4053 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4054 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4055 ioc->name, ioc->reply_sz, ioc->reply_depth));
4056 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4057 ioc->name, reply_sz, reply_sz));
4058
4059 sz = (ioc->req_sz * ioc->req_depth);
4060 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4061 ioc->name, ioc->req_sz, ioc->req_depth));
4062 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4063 ioc->name, sz, sz));
4064 total_size += sz;
4065
4066 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4067 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4068 ioc->name, ioc->req_sz, num_chain));
4069 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4070 ioc->name, sz, sz, num_chain));
4071
4072 total_size += sz;
4073 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4074 if (mem == NULL) {
4075 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4076 ioc->name);
4077 goto out_fail;
4078 }
4079
4080 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4081 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4082
4083 memset(mem, 0, total_size);
4084 ioc->alloc_total += total_size;
4085 ioc->alloc = mem;
4086 ioc->alloc_dma = alloc_dma;
4087 ioc->alloc_sz = total_size;
4088 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4089 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4090
4091 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4092 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4093
4094 alloc_dma += reply_sz;
4095 mem += reply_sz;
4096
4097 /* Request FIFO - WE manage this! */
4098
4099 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4100 ioc->req_frames_dma = alloc_dma;
4101
4102 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4103 ioc->name, mem, (void *)(ulong)alloc_dma));
4104
4105 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4106
4107 #if defined(CONFIG_MTRR) && 0
4108 /*
4109 * Enable Write Combining MTRR for IOC's memory region.
4110 * (at least as much as we can; "size and base must be
4111 * multiples of 4 kiB"
4112 */
4113 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4114 sz,
4115 MTRR_TYPE_WRCOMB, 1);
4116 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4117 ioc->name, ioc->req_frames_dma, sz));
4118 #endif
4119
4120 for (i = 0; i < ioc->req_depth; i++) {
4121 alloc_dma += ioc->req_sz;
4122 mem += ioc->req_sz;
4123 }
4124
4125 ioc->ChainBuffer = mem;
4126 ioc->ChainBufferDMA = alloc_dma;
4127
4128 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4129 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4130
4131 /* Initialize the free chain Q.
4132 */
4133
4134 INIT_LIST_HEAD(&ioc->FreeChainQ);
4135
4136 /* Post the chain buffers to the FreeChainQ.
4137 */
4138 mem = (u8 *)ioc->ChainBuffer;
4139 for (i=0; i < num_chain; i++) {
4140 mf = (MPT_FRAME_HDR *) mem;
4141 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4142 mem += ioc->req_sz;
4143 }
4144
4145 /* Initialize Request frames linked list
4146 */
4147 alloc_dma = ioc->req_frames_dma;
4148 mem = (u8 *) ioc->req_frames;
4149
4150 spin_lock_irqsave(&ioc->FreeQlock, flags);
4151 INIT_LIST_HEAD(&ioc->FreeQ);
4152 for (i = 0; i < ioc->req_depth; i++) {
4153 mf = (MPT_FRAME_HDR *) mem;
4154
4155 /* Queue REQUESTs *internally*! */
4156 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4157
4158 mem += ioc->req_sz;
4159 }
4160 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4161
4162 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4163 ioc->sense_buf_pool =
4164 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4165 if (ioc->sense_buf_pool == NULL) {
4166 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4167 ioc->name);
4168 goto out_fail;
4169 }
4170
4171 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4172 ioc->alloc_total += sz;
4173 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4174 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4175
4176 }
4177
4178 /* Post Reply frames to FIFO
4179 */
4180 alloc_dma = ioc->alloc_dma;
4181 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4182 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4183
4184 for (i = 0; i < ioc->reply_depth; i++) {
4185 /* Write each address to the IOC! */
4186 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4187 alloc_dma += ioc->reply_sz;
4188 }
4189
4190 return 0;
4191
4192 out_fail:
4193 if (ioc->alloc != NULL) {
4194 sz = ioc->alloc_sz;
4195 pci_free_consistent(ioc->pcidev,
4196 sz,
4197 ioc->alloc, ioc->alloc_dma);
4198 ioc->reply_frames = NULL;
4199 ioc->req_frames = NULL;
4200 ioc->alloc_total -= sz;
4201 }
4202 if (ioc->sense_buf_pool != NULL) {
4203 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4204 pci_free_consistent(ioc->pcidev,
4205 sz,
4206 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4207 ioc->sense_buf_pool = NULL;
4208 }
4209 return -1;
4210 }
4211
4212 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4213 /**
4214 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4215 * from IOC via doorbell handshake method.
4216 * @ioc: Pointer to MPT_ADAPTER structure
4217 * @reqBytes: Size of the request in bytes
4218 * @req: Pointer to MPT request frame
4219 * @replyBytes: Expected size of the reply in bytes
4220 * @u16reply: Pointer to area where reply should be written
4221 * @maxwait: Max wait time for a reply (in seconds)
4222 * @sleepFlag: Specifies whether the process can sleep
4223 *
4224 * NOTES: It is the callers responsibility to byte-swap fields in the
4225 * request which are greater than 1 byte in size. It is also the
4226 * callers responsibility to byte-swap response fields which are
4227 * greater than 1 byte in size.
4228 *
4229 * Returns 0 for success, non-zero for failure.
4230 */
4231 static int
4232 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4233 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4234 {
4235 MPIDefaultReply_t *mptReply;
4236 int failcnt = 0;
4237 int t;
4238
4239 /*
4240 * Get ready to cache a handshake reply
4241 */
4242 ioc->hs_reply_idx = 0;
4243 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4244 mptReply->MsgLength = 0;
4245
4246 /*
4247 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4248 * then tell IOC that we want to handshake a request of N words.
4249 * (WRITE u32val to Doorbell reg).
4250 */
4251 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4252 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4253 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4254 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4255
4256 /*
4257 * Wait for IOC's doorbell handshake int
4258 */
4259 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4260 failcnt++;
4261
4262 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4263 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4264
4265 /* Read doorbell and check for active bit */
4266 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4267 return -1;
4268
4269 /*
4270 * Clear doorbell int (WRITE 0 to IntStatus reg),
4271 * then wait for IOC to ACKnowledge that it's ready for
4272 * our handshake request.
4273 */
4274 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4275 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4276 failcnt++;
4277
4278 if (!failcnt) {
4279 int ii;
4280 u8 *req_as_bytes = (u8 *) req;
4281
4282 /*
4283 * Stuff request words via doorbell handshake,
4284 * with ACK from IOC for each.
4285 */
4286 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4287 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4288 (req_as_bytes[(ii*4) + 1] << 8) |
4289 (req_as_bytes[(ii*4) + 2] << 16) |
4290 (req_as_bytes[(ii*4) + 3] << 24));
4291
4292 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4293 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4294 failcnt++;
4295 }
4296
4297 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4298 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4299
4300 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4301 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4302
4303 /*
4304 * Wait for completion of doorbell handshake reply from the IOC
4305 */
4306 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4307 failcnt++;
4308
4309 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4310 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4311
4312 /*
4313 * Copy out the cached reply...
4314 */
4315 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4316 u16reply[ii] = ioc->hs_reply[ii];
4317 } else {
4318 return -99;
4319 }
4320
4321 return -failcnt;
4322 }
4323
4324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4325 /**
4326 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4327 * @ioc: Pointer to MPT_ADAPTER structure
4328 * @howlong: How long to wait (in seconds)
4329 * @sleepFlag: Specifies whether the process can sleep
4330 *
4331 * This routine waits (up to ~2 seconds max) for IOC doorbell
4332 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4333 * bit in its IntStatus register being clear.
4334 *
4335 * Returns a negative value on failure, else wait loop count.
4336 */
4337 static int
4338 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4339 {
4340 int cntdn;
4341 int count = 0;
4342 u32 intstat=0;
4343
4344 cntdn = 1000 * howlong;
4345
4346 if (sleepFlag == CAN_SLEEP) {
4347 while (--cntdn) {
4348 msleep (1);
4349 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4350 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4351 break;
4352 count++;
4353 }
4354 } else {
4355 while (--cntdn) {
4356 udelay (1000);
4357 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4358 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4359 break;
4360 count++;
4361 }
4362 }
4363
4364 if (cntdn) {
4365 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4366 ioc->name, count));
4367 return count;
4368 }
4369
4370 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4371 ioc->name, count, intstat);
4372 return -1;
4373 }
4374
4375 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4376 /**
4377 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4378 * @ioc: Pointer to MPT_ADAPTER structure
4379 * @howlong: How long to wait (in seconds)
4380 * @sleepFlag: Specifies whether the process can sleep
4381 *
4382 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4383 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4384 *
4385 * Returns a negative value on failure, else wait loop count.
4386 */
4387 static int
4388 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4389 {
4390 int cntdn;
4391 int count = 0;
4392 u32 intstat=0;
4393
4394 cntdn = 1000 * howlong;
4395 if (sleepFlag == CAN_SLEEP) {
4396 while (--cntdn) {
4397 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4398 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4399 break;
4400 msleep(1);
4401 count++;
4402 }
4403 } else {
4404 while (--cntdn) {
4405 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4406 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4407 break;
4408 udelay (1000);
4409 count++;
4410 }
4411 }
4412
4413 if (cntdn) {
4414 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4415 ioc->name, count, howlong));
4416 return count;
4417 }
4418
4419 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4420 ioc->name, count, intstat);
4421 return -1;
4422 }
4423
4424 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4425 /**
4426 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4427 * @ioc: Pointer to MPT_ADAPTER structure
4428 * @howlong: How long to wait (in seconds)
4429 * @sleepFlag: Specifies whether the process can sleep
4430 *
4431 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4432 * Reply is cached to IOC private area large enough to hold a maximum
4433 * of 128 bytes of reply data.
4434 *
4435 * Returns a negative value on failure, else size of reply in WORDS.
4436 */
4437 static int
4438 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4439 {
4440 int u16cnt = 0;
4441 int failcnt = 0;
4442 int t;
4443 u16 *hs_reply = ioc->hs_reply;
4444 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4445 u16 hword;
4446
4447 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4448
4449 /*
4450 * Get first two u16's so we can look at IOC's intended reply MsgLength
4451 */
4452 u16cnt=0;
4453 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4454 failcnt++;
4455 } else {
4456 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4457 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4458 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4459 failcnt++;
4460 else {
4461 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4462 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4463 }
4464 }
4465
4466 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4467 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4468 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4469
4470 /*
4471 * If no error (and IOC said MsgLength is > 0), piece together
4472 * reply 16 bits at a time.
4473 */
4474 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4475 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4476 failcnt++;
4477 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4478 /* don't overflow our IOC hs_reply[] buffer! */
4479 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4480 hs_reply[u16cnt] = hword;
4481 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4482 }
4483
4484 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4485 failcnt++;
4486 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4487
4488 if (failcnt) {
4489 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4490 ioc->name);
4491 return -failcnt;
4492 }
4493 #if 0
4494 else if (u16cnt != (2 * mptReply->MsgLength)) {
4495 return -101;
4496 }
4497 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4498 return -102;
4499 }
4500 #endif
4501
4502 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4503 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4504
4505 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4506 ioc->name, t, u16cnt/2));
4507 return u16cnt/2;
4508 }
4509
4510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4511 /**
4512 * GetLanConfigPages - Fetch LANConfig pages.
4513 * @ioc: Pointer to MPT_ADAPTER structure
4514 *
4515 * Return: 0 for success
4516 * -ENOMEM if no memory available
4517 * -EPERM if not allowed due to ISR context
4518 * -EAGAIN if no msg frames currently available
4519 * -EFAULT for non-successful reply or no reply (timeout)
4520 */
4521 static int
4522 GetLanConfigPages(MPT_ADAPTER *ioc)
4523 {
4524 ConfigPageHeader_t hdr;
4525 CONFIGPARMS cfg;
4526 LANPage0_t *ppage0_alloc;
4527 dma_addr_t page0_dma;
4528 LANPage1_t *ppage1_alloc;
4529 dma_addr_t page1_dma;
4530 int rc = 0;
4531 int data_sz;
4532 int copy_sz;
4533
4534 /* Get LAN Page 0 header */
4535 hdr.PageVersion = 0;
4536 hdr.PageLength = 0;
4537 hdr.PageNumber = 0;
4538 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4539 cfg.cfghdr.hdr = &hdr;
4540 cfg.physAddr = -1;
4541 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4542 cfg.dir = 0;
4543 cfg.pageAddr = 0;
4544 cfg.timeout = 0;
4545
4546 if ((rc = mpt_config(ioc, &cfg)) != 0)
4547 return rc;
4548
4549 if (hdr.PageLength > 0) {
4550 data_sz = hdr.PageLength * 4;
4551 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4552 rc = -ENOMEM;
4553 if (ppage0_alloc) {
4554 memset((u8 *)ppage0_alloc, 0, data_sz);
4555 cfg.physAddr = page0_dma;
4556 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4557
4558 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4559 /* save the data */
4560 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4561 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4562
4563 }
4564
4565 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4566
4567 /* FIXME!
4568 * Normalize endianness of structure data,
4569 * by byte-swapping all > 1 byte fields!
4570 */
4571
4572 }
4573
4574 if (rc)
4575 return rc;
4576 }
4577
4578 /* Get LAN Page 1 header */
4579 hdr.PageVersion = 0;
4580 hdr.PageLength = 0;
4581 hdr.PageNumber = 1;
4582 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4583 cfg.cfghdr.hdr = &hdr;
4584 cfg.physAddr = -1;
4585 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4586 cfg.dir = 0;
4587 cfg.pageAddr = 0;
4588
4589 if ((rc = mpt_config(ioc, &cfg)) != 0)
4590 return rc;
4591
4592 if (hdr.PageLength == 0)
4593 return 0;
4594
4595 data_sz = hdr.PageLength * 4;
4596 rc = -ENOMEM;
4597 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4598 if (ppage1_alloc) {
4599 memset((u8 *)ppage1_alloc, 0, data_sz);
4600 cfg.physAddr = page1_dma;
4601 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4602
4603 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4604 /* save the data */
4605 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4606 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4607 }
4608
4609 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4610
4611 /* FIXME!
4612 * Normalize endianness of structure data,
4613 * by byte-swapping all > 1 byte fields!
4614 */
4615
4616 }
4617
4618 return rc;
4619 }
4620
4621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4622 /**
4623 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4624 * @ioc: Pointer to MPT_ADAPTER structure
4625 * @persist_opcode: see below
4626 *
4627 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4628 * devices not currently present.
4629 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4630 *
4631 * NOTE: Don't use not this function during interrupt time.
4632 *
4633 * Returns 0 for success, non-zero error
4634 */
4635
4636 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4637 int
4638 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4639 {
4640 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4641 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4642 MPT_FRAME_HDR *mf = NULL;
4643 MPIHeader_t *mpi_hdr;
4644
4645
4646 /* insure garbage is not sent to fw */
4647 switch(persist_opcode) {
4648
4649 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4650 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4651 break;
4652
4653 default:
4654 return -1;
4655 break;
4656 }
4657
4658 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4659
4660 /* Get a MF for this command.
4661 */
4662 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4663 printk("%s: no msg frames!\n",__FUNCTION__);
4664 return -1;
4665 }
4666
4667 mpi_hdr = (MPIHeader_t *) mf;
4668 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4669 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4670 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4671 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4672 sasIoUnitCntrReq->Operation = persist_opcode;
4673
4674 init_timer(&ioc->persist_timer);
4675 ioc->persist_timer.data = (unsigned long) ioc;
4676 ioc->persist_timer.function = mpt_timer_expired;
4677 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4678 ioc->persist_wait_done=0;
4679 add_timer(&ioc->persist_timer);
4680 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4681 wait_event(mpt_waitq, ioc->persist_wait_done);
4682
4683 sasIoUnitCntrReply =
4684 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4685 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4686 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4687 __FUNCTION__,
4688 sasIoUnitCntrReply->IOCStatus,
4689 sasIoUnitCntrReply->IOCLogInfo);
4690 return -1;
4691 }
4692
4693 printk("%s: success\n",__FUNCTION__);
4694 return 0;
4695 }
4696
4697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4698
4699 static void
4700 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4701 MpiEventDataRaid_t * pRaidEventData)
4702 {
4703 int volume;
4704 int reason;
4705 int disk;
4706 int status;
4707 int flags;
4708 int state;
4709
4710 volume = pRaidEventData->VolumeID;
4711 reason = pRaidEventData->ReasonCode;
4712 disk = pRaidEventData->PhysDiskNum;
4713 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4714 flags = (status >> 0) & 0xff;
4715 state = (status >> 8) & 0xff;
4716
4717 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4718 return;
4719 }
4720
4721 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4722 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4723 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4724 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4725 ioc->name, disk, volume);
4726 } else {
4727 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4728 ioc->name, volume);
4729 }
4730
4731 switch(reason) {
4732 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4733 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4734 ioc->name);
4735 break;
4736
4737 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4738
4739 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4740 ioc->name);
4741 break;
4742
4743 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4744 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4745 ioc->name);
4746 break;
4747
4748 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4749 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4750 ioc->name,
4751 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4752 ? "optimal"
4753 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4754 ? "degraded"
4755 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4756 ? "failed"
4757 : "state unknown",
4758 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4759 ? ", enabled" : "",
4760 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4761 ? ", quiesced" : "",
4762 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4763 ? ", resync in progress" : "" );
4764 break;
4765
4766 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4767 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4768 ioc->name, disk);
4769 break;
4770
4771 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4772 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4773 ioc->name);
4774 break;
4775
4776 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4777 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4778 ioc->name);
4779 break;
4780
4781 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4782 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4783 ioc->name);
4784 break;
4785
4786 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4787 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4788 ioc->name,
4789 state == MPI_PHYSDISK0_STATUS_ONLINE
4790 ? "online"
4791 : state == MPI_PHYSDISK0_STATUS_MISSING
4792 ? "missing"
4793 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4794 ? "not compatible"
4795 : state == MPI_PHYSDISK0_STATUS_FAILED
4796 ? "failed"
4797 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4798 ? "initializing"
4799 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4800 ? "offline requested"
4801 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4802 ? "failed requested"
4803 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4804 ? "offline"
4805 : "state unknown",
4806 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4807 ? ", out of sync" : "",
4808 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4809 ? ", quiesced" : "" );
4810 break;
4811
4812 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4813 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4814 ioc->name, disk);
4815 break;
4816
4817 case MPI_EVENT_RAID_RC_SMART_DATA:
4818 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4819 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4820 break;
4821
4822 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4823 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4824 ioc->name, disk);
4825 break;
4826 }
4827 }
4828
4829 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4830 /**
4831 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4832 * @ioc: Pointer to MPT_ADAPTER structure
4833 *
4834 * Returns: 0 for success
4835 * -ENOMEM if no memory available
4836 * -EPERM if not allowed due to ISR context
4837 * -EAGAIN if no msg frames currently available
4838 * -EFAULT for non-successful reply or no reply (timeout)
4839 */
4840 static int
4841 GetIoUnitPage2(MPT_ADAPTER *ioc)
4842 {
4843 ConfigPageHeader_t hdr;
4844 CONFIGPARMS cfg;
4845 IOUnitPage2_t *ppage_alloc;
4846 dma_addr_t page_dma;
4847 int data_sz;
4848 int rc;
4849
4850 /* Get the page header */
4851 hdr.PageVersion = 0;
4852 hdr.PageLength = 0;
4853 hdr.PageNumber = 2;
4854 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4855 cfg.cfghdr.hdr = &hdr;
4856 cfg.physAddr = -1;
4857 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4858 cfg.dir = 0;
4859 cfg.pageAddr = 0;
4860 cfg.timeout = 0;
4861
4862 if ((rc = mpt_config(ioc, &cfg)) != 0)
4863 return rc;
4864
4865 if (hdr.PageLength == 0)
4866 return 0;
4867
4868 /* Read the config page */
4869 data_sz = hdr.PageLength * 4;
4870 rc = -ENOMEM;
4871 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4872 if (ppage_alloc) {
4873 memset((u8 *)ppage_alloc, 0, data_sz);
4874 cfg.physAddr = page_dma;
4875 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4876
4877 /* If Good, save data */
4878 if ((rc = mpt_config(ioc, &cfg)) == 0)
4879 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4880
4881 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4882 }
4883
4884 return rc;
4885 }
4886
4887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4888 /**
4889 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4890 * @ioc: Pointer to a Adapter Strucutre
4891 * @portnum: IOC port number
4892 *
4893 * Return: -EFAULT if read of config page header fails
4894 * or if no nvram
4895 * If read of SCSI Port Page 0 fails,
4896 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4897 * Adapter settings: async, narrow
4898 * Return 1
4899 * If read of SCSI Port Page 2 fails,
4900 * Adapter settings valid
4901 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4902 * Return 1
4903 * Else
4904 * Both valid
4905 * Return 0
4906 * CHECK - what type of locking mechanisms should be used????
4907 */
4908 static int
4909 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4910 {
4911 u8 *pbuf;
4912 dma_addr_t buf_dma;
4913 CONFIGPARMS cfg;
4914 ConfigPageHeader_t header;
4915 int ii;
4916 int data, rc = 0;
4917
4918 /* Allocate memory
4919 */
4920 if (!ioc->spi_data.nvram) {
4921 int sz;
4922 u8 *mem;
4923 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4924 mem = kmalloc(sz, GFP_ATOMIC);
4925 if (mem == NULL)
4926 return -EFAULT;
4927
4928 ioc->spi_data.nvram = (int *) mem;
4929
4930 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4931 ioc->name, ioc->spi_data.nvram, sz));
4932 }
4933
4934 /* Invalidate NVRAM information
4935 */
4936 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4937 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4938 }
4939
4940 /* Read SPP0 header, allocate memory, then read page.
4941 */
4942 header.PageVersion = 0;
4943 header.PageLength = 0;
4944 header.PageNumber = 0;
4945 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4946 cfg.cfghdr.hdr = &header;
4947 cfg.physAddr = -1;
4948 cfg.pageAddr = portnum;
4949 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4950 cfg.dir = 0;
4951 cfg.timeout = 0; /* use default */
4952 if (mpt_config(ioc, &cfg) != 0)
4953 return -EFAULT;
4954
4955 if (header.PageLength > 0) {
4956 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4957 if (pbuf) {
4958 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4959 cfg.physAddr = buf_dma;
4960 if (mpt_config(ioc, &cfg) != 0) {
4961 ioc->spi_data.maxBusWidth = MPT_NARROW;
4962 ioc->spi_data.maxSyncOffset = 0;
4963 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4964 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4965 rc = 1;
4966 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4967 "Unable to read PortPage0 minSyncFactor=%x\n",
4968 ioc->name, ioc->spi_data.minSyncFactor));
4969 } else {
4970 /* Save the Port Page 0 data
4971 */
4972 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4973 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4974 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4975
4976 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4977 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4978 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4979 "noQas due to Capabilities=%x\n",
4980 ioc->name, pPP0->Capabilities));
4981 }
4982 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4983 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4984 if (data) {
4985 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4986 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4987 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4988 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4989 "PortPage0 minSyncFactor=%x\n",
4990 ioc->name, ioc->spi_data.minSyncFactor));
4991 } else {
4992 ioc->spi_data.maxSyncOffset = 0;
4993 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4994 }
4995
4996 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4997
4998 /* Update the minSyncFactor based on bus type.
4999 */
5000 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5001 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5002
5003 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5004 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5005 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5006 "HVD or SE detected, minSyncFactor=%x\n",
5007 ioc->name, ioc->spi_data.minSyncFactor));
5008 }
5009 }
5010 }
5011 if (pbuf) {
5012 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5013 }
5014 }
5015 }
5016
5017 /* SCSI Port Page 2 - Read the header then the page.
5018 */
5019 header.PageVersion = 0;
5020 header.PageLength = 0;
5021 header.PageNumber = 2;
5022 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5023 cfg.cfghdr.hdr = &header;
5024 cfg.physAddr = -1;
5025 cfg.pageAddr = portnum;
5026 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5027 cfg.dir = 0;
5028 if (mpt_config(ioc, &cfg) != 0)
5029 return -EFAULT;
5030
5031 if (header.PageLength > 0) {
5032 /* Allocate memory and read SCSI Port Page 2
5033 */
5034 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5035 if (pbuf) {
5036 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5037 cfg.physAddr = buf_dma;
5038 if (mpt_config(ioc, &cfg) != 0) {
5039 /* Nvram data is left with INVALID mark
5040 */
5041 rc = 1;
5042 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5043
5044 /* This is an ATTO adapter, read Page2 accordingly
5045 */
5046 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5047 ATTODeviceInfo_t *pdevice = NULL;
5048 u16 ATTOFlags;
5049
5050 /* Save the Port Page 2 data
5051 * (reformat into a 32bit quantity)
5052 */
5053 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5054 pdevice = &pPP2->DeviceSettings[ii];
5055 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5056 data = 0;
5057
5058 /* Translate ATTO device flags to LSI format
5059 */
5060 if (ATTOFlags & ATTOFLAG_DISC)
5061 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5062 if (ATTOFlags & ATTOFLAG_ID_ENB)
5063 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5064 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5065 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5066 if (ATTOFlags & ATTOFLAG_TAGGED)
5067 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5068 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5069 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5070
5071 data = (data << 16) | (pdevice->Period << 8) | 10;
5072 ioc->spi_data.nvram[ii] = data;
5073 }
5074 } else {
5075 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5076 MpiDeviceInfo_t *pdevice = NULL;
5077
5078 /*
5079 * Save "Set to Avoid SCSI Bus Resets" flag
5080 */
5081 ioc->spi_data.bus_reset =
5082 (le32_to_cpu(pPP2->PortFlags) &
5083 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5084 0 : 1 ;
5085
5086 /* Save the Port Page 2 data
5087 * (reformat into a 32bit quantity)
5088 */
5089 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5090 ioc->spi_data.PortFlags = data;
5091 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5092 pdevice = &pPP2->DeviceSettings[ii];
5093 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5094 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5095 ioc->spi_data.nvram[ii] = data;
5096 }
5097 }
5098
5099 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5100 }
5101 }
5102
5103 /* Update Adapter limits with those from NVRAM
5104 * Comment: Don't need to do this. Target performance
5105 * parameters will never exceed the adapters limits.
5106 */
5107
5108 return rc;
5109 }
5110
5111 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5112 /**
5113 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5114 * @ioc: Pointer to a Adapter Strucutre
5115 * @portnum: IOC port number
5116 *
5117 * Return: -EFAULT if read of config page header fails
5118 * or 0 if success.
5119 */
5120 static int
5121 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5122 {
5123 CONFIGPARMS cfg;
5124 ConfigPageHeader_t header;
5125
5126 /* Read the SCSI Device Page 1 header
5127 */
5128 header.PageVersion = 0;
5129 header.PageLength = 0;
5130 header.PageNumber = 1;
5131 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5132 cfg.cfghdr.hdr = &header;
5133 cfg.physAddr = -1;
5134 cfg.pageAddr = portnum;
5135 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5136 cfg.dir = 0;
5137 cfg.timeout = 0;
5138 if (mpt_config(ioc, &cfg) != 0)
5139 return -EFAULT;
5140
5141 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5142 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5143
5144 header.PageVersion = 0;
5145 header.PageLength = 0;
5146 header.PageNumber = 0;
5147 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5148 if (mpt_config(ioc, &cfg) != 0)
5149 return -EFAULT;
5150
5151 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5152 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5153
5154 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5155 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5156
5157 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5158 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5159 return 0;
5160 }
5161
5162 /**
5163 * mpt_inactive_raid_list_free - This clears this link list.
5164 * @ioc : pointer to per adapter structure
5165 **/
5166 static void
5167 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5168 {
5169 struct inactive_raid_component_info *component_info, *pNext;
5170
5171 if (list_empty(&ioc->raid_data.inactive_list))
5172 return;
5173
5174 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5175 list_for_each_entry_safe(component_info, pNext,
5176 &ioc->raid_data.inactive_list, list) {
5177 list_del(&component_info->list);
5178 kfree(component_info);
5179 }
5180 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5181 }
5182
5183 /**
5184 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5185 *
5186 * @ioc : pointer to per adapter structure
5187 * @channel : volume channel
5188 * @id : volume target id
5189 **/
5190 static void
5191 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5192 {
5193 CONFIGPARMS cfg;
5194 ConfigPageHeader_t hdr;
5195 dma_addr_t dma_handle;
5196 pRaidVolumePage0_t buffer = NULL;
5197 int i;
5198 RaidPhysDiskPage0_t phys_disk;
5199 struct inactive_raid_component_info *component_info;
5200 int handle_inactive_volumes;
5201
5202 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5203 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5204 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5205 cfg.pageAddr = (channel << 8) + id;
5206 cfg.cfghdr.hdr = &hdr;
5207 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5208
5209 if (mpt_config(ioc, &cfg) != 0)
5210 goto out;
5211
5212 if (!hdr.PageLength)
5213 goto out;
5214
5215 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5216 &dma_handle);
5217
5218 if (!buffer)
5219 goto out;
5220
5221 cfg.physAddr = dma_handle;
5222 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5223
5224 if (mpt_config(ioc, &cfg) != 0)
5225 goto out;
5226
5227 if (!buffer->NumPhysDisks)
5228 goto out;
5229
5230 handle_inactive_volumes =
5231 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5232 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5233 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5234 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5235
5236 if (!handle_inactive_volumes)
5237 goto out;
5238
5239 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5240 for (i = 0; i < buffer->NumPhysDisks; i++) {
5241 if(mpt_raid_phys_disk_pg0(ioc,
5242 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5243 continue;
5244
5245 if ((component_info = kmalloc(sizeof (*component_info),
5246 GFP_KERNEL)) == NULL)
5247 continue;
5248
5249 component_info->volumeID = id;
5250 component_info->volumeBus = channel;
5251 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5252 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5253 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5254 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5255
5256 list_add_tail(&component_info->list,
5257 &ioc->raid_data.inactive_list);
5258 }
5259 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5260
5261 out:
5262 if (buffer)
5263 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5264 dma_handle);
5265 }
5266
5267 /**
5268 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5269 * @ioc: Pointer to a Adapter Structure
5270 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5271 * @phys_disk: requested payload data returned
5272 *
5273 * Return:
5274 * 0 on success
5275 * -EFAULT if read of config page header fails or data pointer not NULL
5276 * -ENOMEM if pci_alloc failed
5277 **/
5278 int
5279 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5280 {
5281 CONFIGPARMS cfg;
5282 ConfigPageHeader_t hdr;
5283 dma_addr_t dma_handle;
5284 pRaidPhysDiskPage0_t buffer = NULL;
5285 int rc;
5286
5287 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5288 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5289
5290 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5291 cfg.cfghdr.hdr = &hdr;
5292 cfg.physAddr = -1;
5293 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5294
5295 if (mpt_config(ioc, &cfg) != 0) {
5296 rc = -EFAULT;
5297 goto out;
5298 }
5299
5300 if (!hdr.PageLength) {
5301 rc = -EFAULT;
5302 goto out;
5303 }
5304
5305 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5306 &dma_handle);
5307
5308 if (!buffer) {
5309 rc = -ENOMEM;
5310 goto out;
5311 }
5312
5313 cfg.physAddr = dma_handle;
5314 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5315 cfg.pageAddr = phys_disk_num;
5316
5317 if (mpt_config(ioc, &cfg) != 0) {
5318 rc = -EFAULT;
5319 goto out;
5320 }
5321
5322 rc = 0;
5323 memcpy(phys_disk, buffer, sizeof(*buffer));
5324 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5325
5326 out:
5327
5328 if (buffer)
5329 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5330 dma_handle);
5331
5332 return rc;
5333 }
5334
5335 /**
5336 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5337 * @ioc: Pointer to a Adapter Strucutre
5338 * @portnum: IOC port number
5339 *
5340 * Return:
5341 * 0 on success
5342 * -EFAULT if read of config page header fails or data pointer not NULL
5343 * -ENOMEM if pci_alloc failed
5344 **/
5345 int
5346 mpt_findImVolumes(MPT_ADAPTER *ioc)
5347 {
5348 IOCPage2_t *pIoc2;
5349 u8 *mem;
5350 dma_addr_t ioc2_dma;
5351 CONFIGPARMS cfg;
5352 ConfigPageHeader_t header;
5353 int rc = 0;
5354 int iocpage2sz;
5355 int i;
5356
5357 if (!ioc->ir_firmware)
5358 return 0;
5359
5360 /* Free the old page
5361 */
5362 kfree(ioc->raid_data.pIocPg2);
5363 ioc->raid_data.pIocPg2 = NULL;
5364 mpt_inactive_raid_list_free(ioc);
5365
5366 /* Read IOCP2 header then the page.
5367 */
5368 header.PageVersion = 0;
5369 header.PageLength = 0;
5370 header.PageNumber = 2;
5371 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5372 cfg.cfghdr.hdr = &header;
5373 cfg.physAddr = -1;
5374 cfg.pageAddr = 0;
5375 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5376 cfg.dir = 0;
5377 cfg.timeout = 0;
5378 if (mpt_config(ioc, &cfg) != 0)
5379 return -EFAULT;
5380
5381 if (header.PageLength == 0)
5382 return -EFAULT;
5383
5384 iocpage2sz = header.PageLength * 4;
5385 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5386 if (!pIoc2)
5387 return -ENOMEM;
5388
5389 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5390 cfg.physAddr = ioc2_dma;
5391 if (mpt_config(ioc, &cfg) != 0)
5392 goto out;
5393
5394 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5395 if (!mem)
5396 goto out;
5397
5398 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5399 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5400
5401 mpt_read_ioc_pg_3(ioc);
5402
5403 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5404 mpt_inactive_raid_volumes(ioc,
5405 pIoc2->RaidVolume[i].VolumeBus,
5406 pIoc2->RaidVolume[i].VolumeID);
5407
5408 out:
5409 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5410
5411 return rc;
5412 }
5413
5414 static int
5415 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5416 {
5417 IOCPage3_t *pIoc3;
5418 u8 *mem;
5419 CONFIGPARMS cfg;
5420 ConfigPageHeader_t header;
5421 dma_addr_t ioc3_dma;
5422 int iocpage3sz = 0;
5423
5424 /* Free the old page
5425 */
5426 kfree(ioc->raid_data.pIocPg3);
5427 ioc->raid_data.pIocPg3 = NULL;
5428
5429 /* There is at least one physical disk.
5430 * Read and save IOC Page 3
5431 */
5432 header.PageVersion = 0;
5433 header.PageLength = 0;
5434 header.PageNumber = 3;
5435 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5436 cfg.cfghdr.hdr = &header;
5437 cfg.physAddr = -1;
5438 cfg.pageAddr = 0;
5439 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5440 cfg.dir = 0;
5441 cfg.timeout = 0;
5442 if (mpt_config(ioc, &cfg) != 0)
5443 return 0;
5444
5445 if (header.PageLength == 0)
5446 return 0;
5447
5448 /* Read Header good, alloc memory
5449 */
5450 iocpage3sz = header.PageLength * 4;
5451 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5452 if (!pIoc3)
5453 return 0;
5454
5455 /* Read the Page and save the data
5456 * into malloc'd memory.
5457 */
5458 cfg.physAddr = ioc3_dma;
5459 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5460 if (mpt_config(ioc, &cfg) == 0) {
5461 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5462 if (mem) {
5463 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5464 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5465 }
5466 }
5467
5468 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5469
5470 return 0;
5471 }
5472
5473 static void
5474 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5475 {
5476 IOCPage4_t *pIoc4;
5477 CONFIGPARMS cfg;
5478 ConfigPageHeader_t header;
5479 dma_addr_t ioc4_dma;
5480 int iocpage4sz;
5481
5482 /* Read and save IOC Page 4
5483 */
5484 header.PageVersion = 0;
5485 header.PageLength = 0;
5486 header.PageNumber = 4;
5487 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5488 cfg.cfghdr.hdr = &header;
5489 cfg.physAddr = -1;
5490 cfg.pageAddr = 0;
5491 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5492 cfg.dir = 0;
5493 cfg.timeout = 0;
5494 if (mpt_config(ioc, &cfg) != 0)
5495 return;
5496
5497 if (header.PageLength == 0)
5498 return;
5499
5500 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5501 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5502 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5503 if (!pIoc4)
5504 return;
5505 ioc->alloc_total += iocpage4sz;
5506 } else {
5507 ioc4_dma = ioc->spi_data.IocPg4_dma;
5508 iocpage4sz = ioc->spi_data.IocPg4Sz;
5509 }
5510
5511 /* Read the Page into dma memory.
5512 */
5513 cfg.physAddr = ioc4_dma;
5514 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5515 if (mpt_config(ioc, &cfg) == 0) {
5516 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5517 ioc->spi_data.IocPg4_dma = ioc4_dma;
5518 ioc->spi_data.IocPg4Sz = iocpage4sz;
5519 } else {
5520 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5521 ioc->spi_data.pIocPg4 = NULL;
5522 ioc->alloc_total -= iocpage4sz;
5523 }
5524 }
5525
5526 static void
5527 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5528 {
5529 IOCPage1_t *pIoc1;
5530 CONFIGPARMS cfg;
5531 ConfigPageHeader_t header;
5532 dma_addr_t ioc1_dma;
5533 int iocpage1sz = 0;
5534 u32 tmp;
5535
5536 /* Check the Coalescing Timeout in IOC Page 1
5537 */
5538 header.PageVersion = 0;
5539 header.PageLength = 0;
5540 header.PageNumber = 1;
5541 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5542 cfg.cfghdr.hdr = &header;
5543 cfg.physAddr = -1;
5544 cfg.pageAddr = 0;
5545 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5546 cfg.dir = 0;
5547 cfg.timeout = 0;
5548 if (mpt_config(ioc, &cfg) != 0)
5549 return;
5550
5551 if (header.PageLength == 0)
5552 return;
5553
5554 /* Read Header good, alloc memory
5555 */
5556 iocpage1sz = header.PageLength * 4;
5557 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5558 if (!pIoc1)
5559 return;
5560
5561 /* Read the Page and check coalescing timeout
5562 */
5563 cfg.physAddr = ioc1_dma;
5564 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5565 if (mpt_config(ioc, &cfg) == 0) {
5566
5567 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5568 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5569 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5570
5571 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5572 ioc->name, tmp));
5573
5574 if (tmp > MPT_COALESCING_TIMEOUT) {
5575 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5576
5577 /* Write NVRAM and current
5578 */
5579 cfg.dir = 1;
5580 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5581 if (mpt_config(ioc, &cfg) == 0) {
5582 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5583 ioc->name, MPT_COALESCING_TIMEOUT));
5584
5585 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5586 if (mpt_config(ioc, &cfg) == 0) {
5587 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5588 "Reset NVRAM Coalescing Timeout to = %d\n",
5589 ioc->name, MPT_COALESCING_TIMEOUT));
5590 } else {
5591 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5592 "Reset NVRAM Coalescing Timeout Failed\n",
5593 ioc->name));
5594 }
5595
5596 } else {
5597 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5598 "Reset of Current Coalescing Timeout Failed!\n",
5599 ioc->name));
5600 }
5601 }
5602
5603 } else {
5604 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5605 }
5606 }
5607
5608 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5609
5610 return;
5611 }
5612
5613 static void
5614 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5615 {
5616 CONFIGPARMS cfg;
5617 ConfigPageHeader_t hdr;
5618 dma_addr_t buf_dma;
5619 ManufacturingPage0_t *pbuf = NULL;
5620
5621 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5622 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5623
5624 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5625 cfg.cfghdr.hdr = &hdr;
5626 cfg.physAddr = -1;
5627 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5628 cfg.timeout = 10;
5629
5630 if (mpt_config(ioc, &cfg) != 0)
5631 goto out;
5632
5633 if (!cfg.cfghdr.hdr->PageLength)
5634 goto out;
5635
5636 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5637 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5638 if (!pbuf)
5639 goto out;
5640
5641 cfg.physAddr = buf_dma;
5642
5643 if (mpt_config(ioc, &cfg) != 0)
5644 goto out;
5645
5646 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5647 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5648 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5649
5650 out:
5651
5652 if (pbuf)
5653 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5654 }
5655
5656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5657 /**
5658 * SendEventNotification - Send EventNotification (on or off) request to adapter
5659 * @ioc: Pointer to MPT_ADAPTER structure
5660 * @EvSwitch: Event switch flags
5661 */
5662 static int
5663 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5664 {
5665 EventNotification_t *evnp;
5666
5667 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5668 if (evnp == NULL) {
5669 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5670 ioc->name));
5671 return 0;
5672 }
5673 memset(evnp, 0, sizeof(*evnp));
5674
5675 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5676
5677 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5678 evnp->ChainOffset = 0;
5679 evnp->MsgFlags = 0;
5680 evnp->Switch = EvSwitch;
5681
5682 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5683
5684 return 0;
5685 }
5686
5687 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5688 /**
5689 * SendEventAck - Send EventAck request to MPT adapter.
5690 * @ioc: Pointer to MPT_ADAPTER structure
5691 * @evnp: Pointer to original EventNotification request
5692 */
5693 static int
5694 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5695 {
5696 EventAck_t *pAck;
5697
5698 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5699 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5700 ioc->name,__FUNCTION__));
5701 return -1;
5702 }
5703
5704 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5705
5706 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5707 pAck->ChainOffset = 0;
5708 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5709 pAck->MsgFlags = 0;
5710 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5711 pAck->Event = evnp->Event;
5712 pAck->EventContext = evnp->EventContext;
5713
5714 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5715
5716 return 0;
5717 }
5718
5719 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5720 /**
5721 * mpt_config - Generic function to issue config message
5722 * @ioc: Pointer to an adapter structure
5723 * @pCfg: Pointer to a configuration structure. Struct contains
5724 * action, page address, direction, physical address
5725 * and pointer to a configuration page header
5726 * Page header is updated.
5727 *
5728 * Returns 0 for success
5729 * -EPERM if not allowed due to ISR context
5730 * -EAGAIN if no msg frames currently available
5731 * -EFAULT for non-successful reply or no reply (timeout)
5732 */
5733 int
5734 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5735 {
5736 Config_t *pReq;
5737 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5738 MPT_FRAME_HDR *mf;
5739 unsigned long flags;
5740 int ii, rc;
5741 int flagsLength;
5742 int in_isr;
5743
5744 /* Prevent calling wait_event() (below), if caller happens
5745 * to be in ISR context, because that is fatal!
5746 */
5747 in_isr = in_interrupt();
5748 if (in_isr) {
5749 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5750 ioc->name));
5751 return -EPERM;
5752 }
5753
5754 /* Get and Populate a free Frame
5755 */
5756 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5757 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5758 ioc->name));
5759 return -EAGAIN;
5760 }
5761 pReq = (Config_t *)mf;
5762 pReq->Action = pCfg->action;
5763 pReq->Reserved = 0;
5764 pReq->ChainOffset = 0;
5765 pReq->Function = MPI_FUNCTION_CONFIG;
5766
5767 /* Assume page type is not extended and clear "reserved" fields. */
5768 pReq->ExtPageLength = 0;
5769 pReq->ExtPageType = 0;
5770 pReq->MsgFlags = 0;
5771
5772 for (ii=0; ii < 8; ii++)
5773 pReq->Reserved2[ii] = 0;
5774
5775 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5776 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5777 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5778 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5779
5780 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5781 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5782 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5783 pReq->ExtPageType = pExtHdr->ExtPageType;
5784 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5785
5786 /* Page Length must be treated as a reserved field for the extended header. */
5787 pReq->Header.PageLength = 0;
5788 }
5789
5790 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5791
5792 /* Add a SGE to the config request.
5793 */
5794 if (pCfg->dir)
5795 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5796 else
5797 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5798
5799 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5800 flagsLength |= pExtHdr->ExtPageLength * 4;
5801
5802 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5803 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5804 }
5805 else {
5806 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5807
5808 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5809 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5810 }
5811
5812 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5813
5814 /* Append pCfg pointer to end of mf
5815 */
5816 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5817
5818 /* Initalize the timer
5819 */
5820 init_timer(&pCfg->timer);
5821 pCfg->timer.data = (unsigned long) ioc;
5822 pCfg->timer.function = mpt_timer_expired;
5823 pCfg->wait_done = 0;
5824
5825 /* Set the timer; ensure 10 second minimum */
5826 if (pCfg->timeout < 10)
5827 pCfg->timer.expires = jiffies + HZ*10;
5828 else
5829 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5830
5831 /* Add to end of Q, set timer and then issue this command */
5832 spin_lock_irqsave(&ioc->FreeQlock, flags);
5833 list_add_tail(&pCfg->linkage, &ioc->configQ);
5834 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5835
5836 add_timer(&pCfg->timer);
5837 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5838 wait_event(mpt_waitq, pCfg->wait_done);
5839
5840 /* mf has been freed - do not access */
5841
5842 rc = pCfg->status;
5843
5844 return rc;
5845 }
5846
5847 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5848 /**
5849 * mpt_timer_expired - Callback for timer process.
5850 * Used only internal config functionality.
5851 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5852 */
5853 static void
5854 mpt_timer_expired(unsigned long data)
5855 {
5856 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5857
5858 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5859
5860 /* Perform a FW reload */
5861 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5862 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5863
5864 /* No more processing.
5865 * Hard reset clean-up will wake up
5866 * process and free all resources.
5867 */
5868 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5869
5870 return;
5871 }
5872
5873 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5874 /**
5875 * mpt_ioc_reset - Base cleanup for hard reset
5876 * @ioc: Pointer to the adapter structure
5877 * @reset_phase: Indicates pre- or post-reset functionality
5878 *
5879 * Remark: Frees resources with internally generated commands.
5880 */
5881 static int
5882 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5883 {
5884 CONFIGPARMS *pCfg;
5885 unsigned long flags;
5886
5887 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5888 ": IOC %s_reset routed to MPT base driver!\n",
5889 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5890 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5891
5892 if (reset_phase == MPT_IOC_SETUP_RESET) {
5893 ;
5894 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5895 /* If the internal config Q is not empty -
5896 * delete timer. MF resources will be freed when
5897 * the FIFO's are primed.
5898 */
5899 spin_lock_irqsave(&ioc->FreeQlock, flags);
5900 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5901 del_timer(&pCfg->timer);
5902 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5903
5904 } else {
5905 CONFIGPARMS *pNext;
5906
5907 /* Search the configQ for internal commands.
5908 * Flush the Q, and wake up all suspended threads.
5909 */
5910 spin_lock_irqsave(&ioc->FreeQlock, flags);
5911 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5912 list_del(&pCfg->linkage);
5913
5914 pCfg->status = MPT_CONFIG_ERROR;
5915 pCfg->wait_done = 1;
5916 wake_up(&mpt_waitq);
5917 }
5918 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5919 }
5920
5921 return 1; /* currently means nothing really */
5922 }
5923
5924
5925 #ifdef CONFIG_PROC_FS /* { */
5926 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5927 /*
5928 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5929 */
5930 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5931 /**
5932 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5933 *
5934 * Returns 0 for success, non-zero for failure.
5935 */
5936 static int
5937 procmpt_create(void)
5938 {
5939 struct proc_dir_entry *ent;
5940
5941 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5942 if (mpt_proc_root_dir == NULL)
5943 return -ENOTDIR;
5944
5945 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5946 if (ent)
5947 ent->read_proc = procmpt_summary_read;
5948
5949 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5950 if (ent)
5951 ent->read_proc = procmpt_version_read;
5952
5953 return 0;
5954 }
5955
5956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5957 /**
5958 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5959 *
5960 * Returns 0 for success, non-zero for failure.
5961 */
5962 static void
5963 procmpt_destroy(void)
5964 {
5965 remove_proc_entry("version", mpt_proc_root_dir);
5966 remove_proc_entry("summary", mpt_proc_root_dir);
5967 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5968 }
5969
5970 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5971 /**
5972 * procmpt_summary_read - Handle read request of a summary file
5973 * @buf: Pointer to area to write information
5974 * @start: Pointer to start pointer
5975 * @offset: Offset to start writing
5976 * @request: Amount of read data requested
5977 * @eof: Pointer to EOF integer
5978 * @data: Pointer
5979 *
5980 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5981 * Returns number of characters written to process performing the read.
5982 */
5983 static int
5984 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5985 {
5986 MPT_ADAPTER *ioc;
5987 char *out = buf;
5988 int len;
5989
5990 if (data) {
5991 int more = 0;
5992
5993 ioc = data;
5994 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5995
5996 out += more;
5997 } else {
5998 list_for_each_entry(ioc, &ioc_list, list) {
5999 int more = 0;
6000
6001 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6002
6003 out += more;
6004 if ((out-buf) >= request)
6005 break;
6006 }
6007 }
6008
6009 len = out - buf;
6010
6011 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6012 }
6013
6014 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6015 /**
6016 * procmpt_version_read - Handle read request from /proc/mpt/version.
6017 * @buf: Pointer to area to write information
6018 * @start: Pointer to start pointer
6019 * @offset: Offset to start writing
6020 * @request: Amount of read data requested
6021 * @eof: Pointer to EOF integer
6022 * @data: Pointer
6023 *
6024 * Returns number of characters written to process performing the read.
6025 */
6026 static int
6027 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6028 {
6029 u8 cb_idx;
6030 int scsi, fc, sas, lan, ctl, targ, dmp;
6031 char *drvname;
6032 int len;
6033
6034 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6035 len += sprintf(buf+len, " Fusion MPT base driver\n");
6036
6037 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6038 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6039 drvname = NULL;
6040 if (MptCallbacks[cb_idx]) {
6041 switch (MptDriverClass[cb_idx]) {
6042 case MPTSPI_DRIVER:
6043 if (!scsi++) drvname = "SPI host";
6044 break;
6045 case MPTFC_DRIVER:
6046 if (!fc++) drvname = "FC host";
6047 break;
6048 case MPTSAS_DRIVER:
6049 if (!sas++) drvname = "SAS host";
6050 break;
6051 case MPTLAN_DRIVER:
6052 if (!lan++) drvname = "LAN";
6053 break;
6054 case MPTSTM_DRIVER:
6055 if (!targ++) drvname = "SCSI target";
6056 break;
6057 case MPTCTL_DRIVER:
6058 if (!ctl++) drvname = "ioctl";
6059 break;
6060 }
6061
6062 if (drvname)
6063 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6064 }
6065 }
6066
6067 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6068 }
6069
6070 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6071 /**
6072 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6073 * @buf: Pointer to area to write information
6074 * @start: Pointer to start pointer
6075 * @offset: Offset to start writing
6076 * @request: Amount of read data requested
6077 * @eof: Pointer to EOF integer
6078 * @data: Pointer
6079 *
6080 * Returns number of characters written to process performing the read.
6081 */
6082 static int
6083 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6084 {
6085 MPT_ADAPTER *ioc = data;
6086 int len;
6087 char expVer[32];
6088 int sz;
6089 int p;
6090
6091 mpt_get_fw_exp_ver(expVer, ioc);
6092
6093 len = sprintf(buf, "%s:", ioc->name);
6094 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6095 len += sprintf(buf+len, " (f/w download boot flag set)");
6096 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6097 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6098
6099 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6100 ioc->facts.ProductID,
6101 ioc->prod_name);
6102 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6103 if (ioc->facts.FWImageSize)
6104 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6105 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6106 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6107 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6108
6109 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6110 ioc->facts.CurrentHostMfaHighAddr);
6111 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6112 ioc->facts.CurrentSenseBufferHighAddr);
6113
6114 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6115 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6116
6117 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6118 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6119 /*
6120 * Rounding UP to nearest 4-kB boundary here...
6121 */
6122 sz = (ioc->req_sz * ioc->req_depth) + 128;
6123 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6124 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6125 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6126 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6127 4*ioc->facts.RequestFrameSize,
6128 ioc->facts.GlobalCredits);
6129
6130 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6131 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6132 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6133 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6134 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6135 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6136 ioc->facts.CurReplyFrameSize,
6137 ioc->facts.ReplyQueueDepth);
6138
6139 len += sprintf(buf+len, " MaxDevices = %d\n",
6140 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6141 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6142
6143 /* per-port info */
6144 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6145 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6146 p+1,
6147 ioc->facts.NumberOfPorts);
6148 if (ioc->bus_type == FC) {
6149 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6150 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6151 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6152 a[5], a[4], a[3], a[2], a[1], a[0]);
6153 }
6154 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6155 ioc->fc_port_page0[p].WWNN.High,
6156 ioc->fc_port_page0[p].WWNN.Low,
6157 ioc->fc_port_page0[p].WWPN.High,
6158 ioc->fc_port_page0[p].WWPN.Low);
6159 }
6160 }
6161
6162 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6163 }
6164
6165 #endif /* CONFIG_PROC_FS } */
6166
6167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6168 static void
6169 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6170 {
6171 buf[0] ='\0';
6172 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6173 sprintf(buf, " (Exp %02d%02d)",
6174 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6175 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6176
6177 /* insider hack! */
6178 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6179 strcat(buf, " [MDBG]");
6180 }
6181 }
6182
6183 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6184 /**
6185 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6186 * @ioc: Pointer to MPT_ADAPTER structure
6187 * @buffer: Pointer to buffer where IOC summary info should be written
6188 * @size: Pointer to number of bytes we wrote (set by this routine)
6189 * @len: Offset at which to start writing in buffer
6190 * @showlan: Display LAN stuff?
6191 *
6192 * This routine writes (english readable) ASCII text, which represents
6193 * a summary of IOC information, to a buffer.
6194 */
6195 void
6196 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6197 {
6198 char expVer[32];
6199 int y;
6200
6201 mpt_get_fw_exp_ver(expVer, ioc);
6202
6203 /*
6204 * Shorter summary of attached ioc's...
6205 */
6206 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6207 ioc->name,
6208 ioc->prod_name,
6209 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6210 ioc->facts.FWVersion.Word,
6211 expVer,
6212 ioc->facts.NumberOfPorts,
6213 ioc->req_depth);
6214
6215 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6216 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6217 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6218 a[5], a[4], a[3], a[2], a[1], a[0]);
6219 }
6220
6221 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6222
6223 if (!ioc->active)
6224 y += sprintf(buffer+len+y, " (disabled)");
6225
6226 y += sprintf(buffer+len+y, "\n");
6227
6228 *size = y;
6229 }
6230
6231 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6232 /*
6233 * Reset Handling
6234 */
6235 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6236 /**
6237 * mpt_HardResetHandler - Generic reset handler
6238 * @ioc: Pointer to MPT_ADAPTER structure
6239 * @sleepFlag: Indicates if sleep or schedule must be called.
6240 *
6241 * Issues SCSI Task Management call based on input arg values.
6242 * If TaskMgmt fails, returns associated SCSI request.
6243 *
6244 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6245 * or a non-interrupt thread. In the former, must not call schedule().
6246 *
6247 * Note: A return of -1 is a FATAL error case, as it means a
6248 * FW reload/initialization failed.
6249 *
6250 * Returns 0 for SUCCESS or -1 if FAILED.
6251 */
6252 int
6253 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6254 {
6255 int rc;
6256 unsigned long flags;
6257
6258 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6259 #ifdef MFCNT
6260 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6261 printk("MF count 0x%x !\n", ioc->mfcnt);
6262 #endif
6263
6264 /* Reset the adapter. Prevent more than 1 call to
6265 * mpt_do_ioc_recovery at any instant in time.
6266 */
6267 spin_lock_irqsave(&ioc->diagLock, flags);
6268 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6269 spin_unlock_irqrestore(&ioc->diagLock, flags);
6270 return 0;
6271 } else {
6272 ioc->diagPending = 1;
6273 }
6274 spin_unlock_irqrestore(&ioc->diagLock, flags);
6275
6276 /* FIXME: If do_ioc_recovery fails, repeat....
6277 */
6278
6279 /* The SCSI driver needs to adjust timeouts on all current
6280 * commands prior to the diagnostic reset being issued.
6281 * Prevents timeouts occurring during a diagnostic reset...very bad.
6282 * For all other protocol drivers, this is a no-op.
6283 */
6284 {
6285 u8 cb_idx;
6286 int r = 0;
6287
6288 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6289 if (MptResetHandlers[cb_idx]) {
6290 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6291 ioc->name, cb_idx));
6292 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6293 if (ioc->alt_ioc) {
6294 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6295 ioc->name, ioc->alt_ioc->name, cb_idx));
6296 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6297 }
6298 }
6299 }
6300 }
6301
6302 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6303 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6304 }
6305 ioc->reload_fw = 0;
6306 if (ioc->alt_ioc)
6307 ioc->alt_ioc->reload_fw = 0;
6308
6309 spin_lock_irqsave(&ioc->diagLock, flags);
6310 ioc->diagPending = 0;
6311 if (ioc->alt_ioc)
6312 ioc->alt_ioc->diagPending = 0;
6313 spin_unlock_irqrestore(&ioc->diagLock, flags);
6314
6315 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6316
6317 return rc;
6318 }
6319
6320 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6321 static void
6322 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6323 {
6324 char *ds = NULL;
6325
6326 switch(event) {
6327 case MPI_EVENT_NONE:
6328 ds = "None";
6329 break;
6330 case MPI_EVENT_LOG_DATA:
6331 ds = "Log Data";
6332 break;
6333 case MPI_EVENT_STATE_CHANGE:
6334 ds = "State Change";
6335 break;
6336 case MPI_EVENT_UNIT_ATTENTION:
6337 ds = "Unit Attention";
6338 break;
6339 case MPI_EVENT_IOC_BUS_RESET:
6340 ds = "IOC Bus Reset";
6341 break;
6342 case MPI_EVENT_EXT_BUS_RESET:
6343 ds = "External Bus Reset";
6344 break;
6345 case MPI_EVENT_RESCAN:
6346 ds = "Bus Rescan Event";
6347 break;
6348 case MPI_EVENT_LINK_STATUS_CHANGE:
6349 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6350 ds = "Link Status(FAILURE) Change";
6351 else
6352 ds = "Link Status(ACTIVE) Change";
6353 break;
6354 case MPI_EVENT_LOOP_STATE_CHANGE:
6355 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6356 ds = "Loop State(LIP) Change";
6357 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6358 ds = "Loop State(LPE) Change"; /* ??? */
6359 else
6360 ds = "Loop State(LPB) Change"; /* ??? */
6361 break;
6362 case MPI_EVENT_LOGOUT:
6363 ds = "Logout";
6364 break;
6365 case MPI_EVENT_EVENT_CHANGE:
6366 if (evData0)
6367 ds = "Events ON";
6368 else
6369 ds = "Events OFF";
6370 break;
6371 case MPI_EVENT_INTEGRATED_RAID:
6372 {
6373 u8 ReasonCode = (u8)(evData0 >> 16);
6374 switch (ReasonCode) {
6375 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6376 ds = "Integrated Raid: Volume Created";
6377 break;
6378 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6379 ds = "Integrated Raid: Volume Deleted";
6380 break;
6381 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6382 ds = "Integrated Raid: Volume Settings Changed";
6383 break;
6384 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6385 ds = "Integrated Raid: Volume Status Changed";
6386 break;
6387 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6388 ds = "Integrated Raid: Volume Physdisk Changed";
6389 break;
6390 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6391 ds = "Integrated Raid: Physdisk Created";
6392 break;
6393 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6394 ds = "Integrated Raid: Physdisk Deleted";
6395 break;
6396 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6397 ds = "Integrated Raid: Physdisk Settings Changed";
6398 break;
6399 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6400 ds = "Integrated Raid: Physdisk Status Changed";
6401 break;
6402 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6403 ds = "Integrated Raid: Domain Validation Needed";
6404 break;
6405 case MPI_EVENT_RAID_RC_SMART_DATA :
6406 ds = "Integrated Raid; Smart Data";
6407 break;
6408 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6409 ds = "Integrated Raid: Replace Action Started";
6410 break;
6411 default:
6412 ds = "Integrated Raid";
6413 break;
6414 }
6415 break;
6416 }
6417 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6418 ds = "SCSI Device Status Change";
6419 break;
6420 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6421 {
6422 u8 id = (u8)(evData0);
6423 u8 channel = (u8)(evData0 >> 8);
6424 u8 ReasonCode = (u8)(evData0 >> 16);
6425 switch (ReasonCode) {
6426 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6427 snprintf(evStr, EVENT_DESCR_STR_SZ,
6428 "SAS Device Status Change: Added: "
6429 "id=%d channel=%d", id, channel);
6430 break;
6431 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6432 snprintf(evStr, EVENT_DESCR_STR_SZ,
6433 "SAS Device Status Change: Deleted: "
6434 "id=%d channel=%d", id, channel);
6435 break;
6436 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6437 snprintf(evStr, EVENT_DESCR_STR_SZ,
6438 "SAS Device Status Change: SMART Data: "
6439 "id=%d channel=%d", id, channel);
6440 break;
6441 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6442 snprintf(evStr, EVENT_DESCR_STR_SZ,
6443 "SAS Device Status Change: No Persistancy: "
6444 "id=%d channel=%d", id, channel);
6445 break;
6446 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6447 snprintf(evStr, EVENT_DESCR_STR_SZ,
6448 "SAS Device Status Change: Unsupported Device "
6449 "Discovered : id=%d channel=%d", id, channel);
6450 break;
6451 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6452 snprintf(evStr, EVENT_DESCR_STR_SZ,
6453 "SAS Device Status Change: Internal Device "
6454 "Reset : id=%d channel=%d", id, channel);
6455 break;
6456 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6457 snprintf(evStr, EVENT_DESCR_STR_SZ,
6458 "SAS Device Status Change: Internal Task "
6459 "Abort : id=%d channel=%d", id, channel);
6460 break;
6461 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6462 snprintf(evStr, EVENT_DESCR_STR_SZ,
6463 "SAS Device Status Change: Internal Abort "
6464 "Task Set : id=%d channel=%d", id, channel);
6465 break;
6466 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6467 snprintf(evStr, EVENT_DESCR_STR_SZ,
6468 "SAS Device Status Change: Internal Clear "
6469 "Task Set : id=%d channel=%d", id, channel);
6470 break;
6471 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6472 snprintf(evStr, EVENT_DESCR_STR_SZ,
6473 "SAS Device Status Change: Internal Query "
6474 "Task : id=%d channel=%d", id, channel);
6475 break;
6476 default:
6477 snprintf(evStr, EVENT_DESCR_STR_SZ,
6478 "SAS Device Status Change: Unknown: "
6479 "id=%d channel=%d", id, channel);
6480 break;
6481 }
6482 break;
6483 }
6484 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6485 ds = "Bus Timer Expired";
6486 break;
6487 case MPI_EVENT_QUEUE_FULL:
6488 {
6489 u16 curr_depth = (u16)(evData0 >> 16);
6490 u8 channel = (u8)(evData0 >> 8);
6491 u8 id = (u8)(evData0);
6492
6493 snprintf(evStr, EVENT_DESCR_STR_SZ,
6494 "Queue Full: channel=%d id=%d depth=%d",
6495 channel, id, curr_depth);
6496 break;
6497 }
6498 case MPI_EVENT_SAS_SES:
6499 ds = "SAS SES Event";
6500 break;
6501 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6502 ds = "Persistent Table Full";
6503 break;
6504 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6505 {
6506 u8 LinkRates = (u8)(evData0 >> 8);
6507 u8 PhyNumber = (u8)(evData0);
6508 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6509 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6510 switch (LinkRates) {
6511 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6512 snprintf(evStr, EVENT_DESCR_STR_SZ,
6513 "SAS PHY Link Status: Phy=%d:"
6514 " Rate Unknown",PhyNumber);
6515 break;
6516 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6517 snprintf(evStr, EVENT_DESCR_STR_SZ,
6518 "SAS PHY Link Status: Phy=%d:"
6519 " Phy Disabled",PhyNumber);
6520 break;
6521 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6522 snprintf(evStr, EVENT_DESCR_STR_SZ,
6523 "SAS PHY Link Status: Phy=%d:"
6524 " Failed Speed Nego",PhyNumber);
6525 break;
6526 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6527 snprintf(evStr, EVENT_DESCR_STR_SZ,
6528 "SAS PHY Link Status: Phy=%d:"
6529 " Sata OOB Completed",PhyNumber);
6530 break;
6531 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6532 snprintf(evStr, EVENT_DESCR_STR_SZ,
6533 "SAS PHY Link Status: Phy=%d:"
6534 " Rate 1.5 Gbps",PhyNumber);
6535 break;
6536 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6537 snprintf(evStr, EVENT_DESCR_STR_SZ,
6538 "SAS PHY Link Status: Phy=%d:"
6539 " Rate 3.0 Gpbs",PhyNumber);
6540 break;
6541 default:
6542 snprintf(evStr, EVENT_DESCR_STR_SZ,
6543 "SAS PHY Link Status: Phy=%d", PhyNumber);
6544 break;
6545 }
6546 break;
6547 }
6548 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6549 ds = "SAS Discovery Error";
6550 break;
6551 case MPI_EVENT_IR_RESYNC_UPDATE:
6552 {
6553 u8 resync_complete = (u8)(evData0 >> 16);
6554 snprintf(evStr, EVENT_DESCR_STR_SZ,
6555 "IR Resync Update: Complete = %d:",resync_complete);
6556 break;
6557 }
6558 case MPI_EVENT_IR2:
6559 {
6560 u8 ReasonCode = (u8)(evData0 >> 16);
6561 switch (ReasonCode) {
6562 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6563 ds = "IR2: LD State Changed";
6564 break;
6565 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6566 ds = "IR2: PD State Changed";
6567 break;
6568 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6569 ds = "IR2: Bad Block Table Full";
6570 break;
6571 case MPI_EVENT_IR2_RC_PD_INSERTED:
6572 ds = "IR2: PD Inserted";
6573 break;
6574 case MPI_EVENT_IR2_RC_PD_REMOVED:
6575 ds = "IR2: PD Removed";
6576 break;
6577 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6578 ds = "IR2: Foreign CFG Detected";
6579 break;
6580 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6581 ds = "IR2: Rebuild Medium Error";
6582 break;
6583 default:
6584 ds = "IR2";
6585 break;
6586 }
6587 break;
6588 }
6589 case MPI_EVENT_SAS_DISCOVERY:
6590 {
6591 if (evData0)
6592 ds = "SAS Discovery: Start";
6593 else
6594 ds = "SAS Discovery: Stop";
6595 break;
6596 }
6597 case MPI_EVENT_LOG_ENTRY_ADDED:
6598 ds = "SAS Log Entry Added";
6599 break;
6600
6601 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6602 {
6603 u8 phy_num = (u8)(evData0);
6604 u8 port_num = (u8)(evData0 >> 8);
6605 u8 port_width = (u8)(evData0 >> 16);
6606 u8 primative = (u8)(evData0 >> 24);
6607 snprintf(evStr, EVENT_DESCR_STR_SZ,
6608 "SAS Broadcase Primative: phy=%d port=%d "
6609 "width=%d primative=0x%02x",
6610 phy_num, port_num, port_width, primative);
6611 break;
6612 }
6613
6614 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6615 {
6616 u8 reason = (u8)(evData0);
6617 u8 port_num = (u8)(evData0 >> 8);
6618 u16 handle = le16_to_cpu(evData0 >> 16);
6619
6620 snprintf(evStr, EVENT_DESCR_STR_SZ,
6621 "SAS Initiator Device Status Change: reason=0x%02x "
6622 "port=%d handle=0x%04x",
6623 reason, port_num, handle);
6624 break;
6625 }
6626
6627 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6628 {
6629 u8 max_init = (u8)(evData0);
6630 u8 current_init = (u8)(evData0 >> 8);
6631
6632 snprintf(evStr, EVENT_DESCR_STR_SZ,
6633 "SAS Initiator Device Table Overflow: max initiators=%02d "
6634 "current initators=%02d",
6635 max_init, current_init);
6636 break;
6637 }
6638 case MPI_EVENT_SAS_SMP_ERROR:
6639 {
6640 u8 status = (u8)(evData0);
6641 u8 port_num = (u8)(evData0 >> 8);
6642 u8 result = (u8)(evData0 >> 16);
6643
6644 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6645 snprintf(evStr, EVENT_DESCR_STR_SZ,
6646 "SAS SMP Error: port=%d result=0x%02x",
6647 port_num, result);
6648 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6649 snprintf(evStr, EVENT_DESCR_STR_SZ,
6650 "SAS SMP Error: port=%d : CRC Error",
6651 port_num);
6652 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6653 snprintf(evStr, EVENT_DESCR_STR_SZ,
6654 "SAS SMP Error: port=%d : Timeout",
6655 port_num);
6656 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6657 snprintf(evStr, EVENT_DESCR_STR_SZ,
6658 "SAS SMP Error: port=%d : No Destination",
6659 port_num);
6660 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6661 snprintf(evStr, EVENT_DESCR_STR_SZ,
6662 "SAS SMP Error: port=%d : Bad Destination",
6663 port_num);
6664 else
6665 snprintf(evStr, EVENT_DESCR_STR_SZ,
6666 "SAS SMP Error: port=%d : status=0x%02x",
6667 port_num, status);
6668 break;
6669 }
6670
6671 /*
6672 * MPT base "custom" events may be added here...
6673 */
6674 default:
6675 ds = "Unknown";
6676 break;
6677 }
6678 if (ds)
6679 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6680 }
6681
6682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6683 /**
6684 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6685 * @ioc: Pointer to MPT_ADAPTER structure
6686 * @pEventReply: Pointer to EventNotification reply frame
6687 * @evHandlers: Pointer to integer, number of event handlers
6688 *
6689 * Routes a received EventNotificationReply to all currently registered
6690 * event handlers.
6691 * Returns sum of event handlers return values.
6692 */
6693 static int
6694 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6695 {
6696 u16 evDataLen;
6697 u32 evData0 = 0;
6698 // u32 evCtx;
6699 int ii;
6700 u8 cb_idx;
6701 int r = 0;
6702 int handlers = 0;
6703 char evStr[EVENT_DESCR_STR_SZ];
6704 u8 event;
6705
6706 /*
6707 * Do platform normalization of values
6708 */
6709 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6710 // evCtx = le32_to_cpu(pEventReply->EventContext);
6711 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6712 if (evDataLen) {
6713 evData0 = le32_to_cpu(pEventReply->Data[0]);
6714 }
6715
6716 EventDescriptionStr(event, evData0, evStr);
6717 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6718 ioc->name,
6719 event,
6720 evStr));
6721
6722 #ifdef CONFIG_FUSION_LOGGING
6723 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6724 ": Event data:\n", ioc->name));
6725 for (ii = 0; ii < evDataLen; ii++)
6726 devtverboseprintk(ioc, printk(" %08x",
6727 le32_to_cpu(pEventReply->Data[ii])));
6728 devtverboseprintk(ioc, printk("\n"));
6729 #endif
6730
6731 /*
6732 * Do general / base driver event processing
6733 */
6734 switch(event) {
6735 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6736 if (evDataLen) {
6737 u8 evState = evData0 & 0xFF;
6738
6739 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6740
6741 /* Update EventState field in cached IocFacts */
6742 if (ioc->facts.Function) {
6743 ioc->facts.EventState = evState;
6744 }
6745 }
6746 break;
6747 case MPI_EVENT_INTEGRATED_RAID:
6748 mptbase_raid_process_event_data(ioc,
6749 (MpiEventDataRaid_t *)pEventReply->Data);
6750 break;
6751 default:
6752 break;
6753 }
6754
6755 /*
6756 * Should this event be logged? Events are written sequentially.
6757 * When buffer is full, start again at the top.
6758 */
6759 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6760 int idx;
6761
6762 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6763
6764 ioc->events[idx].event = event;
6765 ioc->events[idx].eventContext = ioc->eventContext;
6766
6767 for (ii = 0; ii < 2; ii++) {
6768 if (ii < evDataLen)
6769 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6770 else
6771 ioc->events[idx].data[ii] = 0;
6772 }
6773
6774 ioc->eventContext++;
6775 }
6776
6777
6778 /*
6779 * Call each currently registered protocol event handler.
6780 */
6781 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6782 if (MptEvHandlers[cb_idx]) {
6783 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6784 ioc->name, cb_idx));
6785 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6786 handlers++;
6787 }
6788 }
6789 /* FIXME? Examine results here? */
6790
6791 /*
6792 * If needed, send (a single) EventAck.
6793 */
6794 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6795 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6796 "EventAck required\n",ioc->name));
6797 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6798 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6799 ioc->name, ii));
6800 }
6801 }
6802
6803 *evHandlers = handlers;
6804 return r;
6805 }
6806
6807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6808 /**
6809 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6810 * @ioc: Pointer to MPT_ADAPTER structure
6811 * @log_info: U32 LogInfo reply word from the IOC
6812 *
6813 * Refer to lsi/mpi_log_fc.h.
6814 */
6815 static void
6816 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6817 {
6818 char *desc = "unknown";
6819
6820 switch (log_info & 0xFF000000) {
6821 case MPI_IOCLOGINFO_FC_INIT_BASE:
6822 desc = "FCP Initiator";
6823 break;
6824 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6825 desc = "FCP Target";
6826 break;
6827 case MPI_IOCLOGINFO_FC_LAN_BASE:
6828 desc = "LAN";
6829 break;
6830 case MPI_IOCLOGINFO_FC_MSG_BASE:
6831 desc = "MPI Message Layer";
6832 break;
6833 case MPI_IOCLOGINFO_FC_LINK_BASE:
6834 desc = "FC Link";
6835 break;
6836 case MPI_IOCLOGINFO_FC_CTX_BASE:
6837 desc = "Context Manager";
6838 break;
6839 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6840 desc = "Invalid Field Offset";
6841 break;
6842 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6843 desc = "State Change Info";
6844 break;
6845 }
6846
6847 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6848 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6849 }
6850
6851 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6852 /**
6853 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6854 * @ioc: Pointer to MPT_ADAPTER structure
6855 * @mr: Pointer to MPT reply frame
6856 * @log_info: U32 LogInfo word from the IOC
6857 *
6858 * Refer to lsi/sp_log.h.
6859 */
6860 static void
6861 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6862 {
6863 u32 info = log_info & 0x00FF0000;
6864 char *desc = "unknown";
6865
6866 switch (info) {
6867 case 0x00010000:
6868 desc = "bug! MID not found";
6869 if (ioc->reload_fw == 0)
6870 ioc->reload_fw++;
6871 break;
6872
6873 case 0x00020000:
6874 desc = "Parity Error";
6875 break;
6876
6877 case 0x00030000:
6878 desc = "ASYNC Outbound Overrun";
6879 break;
6880
6881 case 0x00040000:
6882 desc = "SYNC Offset Error";
6883 break;
6884
6885 case 0x00050000:
6886 desc = "BM Change";
6887 break;
6888
6889 case 0x00060000:
6890 desc = "Msg In Overflow";
6891 break;
6892
6893 case 0x00070000:
6894 desc = "DMA Error";
6895 break;
6896
6897 case 0x00080000:
6898 desc = "Outbound DMA Overrun";
6899 break;
6900
6901 case 0x00090000:
6902 desc = "Task Management";
6903 break;
6904
6905 case 0x000A0000:
6906 desc = "Device Problem";
6907 break;
6908
6909 case 0x000B0000:
6910 desc = "Invalid Phase Change";
6911 break;
6912
6913 case 0x000C0000:
6914 desc = "Untagged Table Size";
6915 break;
6916
6917 }
6918
6919 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6920 }
6921
6922 /* strings for sas loginfo */
6923 static char *originator_str[] = {
6924 "IOP", /* 00h */
6925 "PL", /* 01h */
6926 "IR" /* 02h */
6927 };
6928 static char *iop_code_str[] = {
6929 NULL, /* 00h */
6930 "Invalid SAS Address", /* 01h */
6931 NULL, /* 02h */
6932 "Invalid Page", /* 03h */
6933 "Diag Message Error", /* 04h */
6934 "Task Terminated", /* 05h */
6935 "Enclosure Management", /* 06h */
6936 "Target Mode" /* 07h */
6937 };
6938 static char *pl_code_str[] = {
6939 NULL, /* 00h */
6940 "Open Failure", /* 01h */
6941 "Invalid Scatter Gather List", /* 02h */
6942 "Wrong Relative Offset or Frame Length", /* 03h */
6943 "Frame Transfer Error", /* 04h */
6944 "Transmit Frame Connected Low", /* 05h */
6945 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6946 "SATA Read Log Receive Data Error", /* 07h */
6947 "SATA NCQ Fail All Commands After Error", /* 08h */
6948 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6949 "Receive Frame Invalid Message", /* 0Ah */
6950 "Receive Context Message Valid Error", /* 0Bh */
6951 "Receive Frame Current Frame Error", /* 0Ch */
6952 "SATA Link Down", /* 0Dh */
6953 "Discovery SATA Init W IOS", /* 0Eh */
6954 "Config Invalid Page", /* 0Fh */
6955 "Discovery SATA Init Timeout", /* 10h */
6956 "Reset", /* 11h */
6957 "Abort", /* 12h */
6958 "IO Not Yet Executed", /* 13h */
6959 "IO Executed", /* 14h */
6960 "Persistent Reservation Out Not Affiliation "
6961 "Owner", /* 15h */
6962 "Open Transmit DMA Abort", /* 16h */
6963 "IO Device Missing Delay Retry", /* 17h */
6964 "IO Cancelled Due to Recieve Error", /* 18h */
6965 NULL, /* 19h */
6966 NULL, /* 1Ah */
6967 NULL, /* 1Bh */
6968 NULL, /* 1Ch */
6969 NULL, /* 1Dh */
6970 NULL, /* 1Eh */
6971 NULL, /* 1Fh */
6972 "Enclosure Management" /* 20h */
6973 };
6974 static char *ir_code_str[] = {
6975 "Raid Action Error", /* 00h */
6976 NULL, /* 00h */
6977 NULL, /* 01h */
6978 NULL, /* 02h */
6979 NULL, /* 03h */
6980 NULL, /* 04h */
6981 NULL, /* 05h */
6982 NULL, /* 06h */
6983 NULL /* 07h */
6984 };
6985 static char *raid_sub_code_str[] = {
6986 NULL, /* 00h */
6987 "Volume Creation Failed: Data Passed too "
6988 "Large", /* 01h */
6989 "Volume Creation Failed: Duplicate Volumes "
6990 "Attempted", /* 02h */
6991 "Volume Creation Failed: Max Number "
6992 "Supported Volumes Exceeded", /* 03h */
6993 "Volume Creation Failed: DMA Error", /* 04h */
6994 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6995 "Volume Creation Failed: Error Reading "
6996 "MFG Page 4", /* 06h */
6997 "Volume Creation Failed: Creating Internal "
6998 "Structures", /* 07h */
6999 NULL, /* 08h */
7000 NULL, /* 09h */
7001 NULL, /* 0Ah */
7002 NULL, /* 0Bh */
7003 NULL, /* 0Ch */
7004 NULL, /* 0Dh */
7005 NULL, /* 0Eh */
7006 NULL, /* 0Fh */
7007 "Activation failed: Already Active Volume", /* 10h */
7008 "Activation failed: Unsupported Volume Type", /* 11h */
7009 "Activation failed: Too Many Active Volumes", /* 12h */
7010 "Activation failed: Volume ID in Use", /* 13h */
7011 "Activation failed: Reported Failure", /* 14h */
7012 "Activation failed: Importing a Volume", /* 15h */
7013 NULL, /* 16h */
7014 NULL, /* 17h */
7015 NULL, /* 18h */
7016 NULL, /* 19h */
7017 NULL, /* 1Ah */
7018 NULL, /* 1Bh */
7019 NULL, /* 1Ch */
7020 NULL, /* 1Dh */
7021 NULL, /* 1Eh */
7022 NULL, /* 1Fh */
7023 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7024 "Phys Disk failed: Data Passed too Large", /* 21h */
7025 "Phys Disk failed: DMA Error", /* 22h */
7026 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7027 "Phys Disk failed: Creating Phys Disk Config "
7028 "Page", /* 24h */
7029 NULL, /* 25h */
7030 NULL, /* 26h */
7031 NULL, /* 27h */
7032 NULL, /* 28h */
7033 NULL, /* 29h */
7034 NULL, /* 2Ah */
7035 NULL, /* 2Bh */
7036 NULL, /* 2Ch */
7037 NULL, /* 2Dh */
7038 NULL, /* 2Eh */
7039 NULL, /* 2Fh */
7040 "Compatibility Error: IR Disabled", /* 30h */
7041 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7042 "Compatibility Error: Device not Direct Access "
7043 "Device ", /* 32h */
7044 "Compatibility Error: Removable Device Found", /* 33h */
7045 "Compatibility Error: Device SCSI Version not "
7046 "2 or Higher", /* 34h */
7047 "Compatibility Error: SATA Device, 48 BIT LBA "
7048 "not Supported", /* 35h */
7049 "Compatibility Error: Device doesn't have "
7050 "512 Byte Block Sizes", /* 36h */
7051 "Compatibility Error: Volume Type Check Failed", /* 37h */
7052 "Compatibility Error: Volume Type is "
7053 "Unsupported by FW", /* 38h */
7054 "Compatibility Error: Disk Drive too Small for "
7055 "use in Volume", /* 39h */
7056 "Compatibility Error: Phys Disk for Create "
7057 "Volume not Found", /* 3Ah */
7058 "Compatibility Error: Too Many or too Few "
7059 "Disks for Volume Type", /* 3Bh */
7060 "Compatibility Error: Disk stripe Sizes "
7061 "Must be 64KB", /* 3Ch */
7062 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7063 };
7064
7065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7066 /**
7067 * mpt_sas_log_info - Log information returned from SAS IOC.
7068 * @ioc: Pointer to MPT_ADAPTER structure
7069 * @log_info: U32 LogInfo reply word from the IOC
7070 *
7071 * Refer to lsi/mpi_log_sas.h.
7072 **/
7073 static void
7074 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7075 {
7076 union loginfo_type {
7077 u32 loginfo;
7078 struct {
7079 u32 subcode:16;
7080 u32 code:8;
7081 u32 originator:4;
7082 u32 bus_type:4;
7083 }dw;
7084 };
7085 union loginfo_type sas_loginfo;
7086 char *originator_desc = NULL;
7087 char *code_desc = NULL;
7088 char *sub_code_desc = NULL;
7089
7090 sas_loginfo.loginfo = log_info;
7091 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7092 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
7093 return;
7094
7095 originator_desc = originator_str[sas_loginfo.dw.originator];
7096
7097 switch (sas_loginfo.dw.originator) {
7098
7099 case 0: /* IOP */
7100 if (sas_loginfo.dw.code <
7101 sizeof(iop_code_str)/sizeof(char*))
7102 code_desc = iop_code_str[sas_loginfo.dw.code];
7103 break;
7104 case 1: /* PL */
7105 if (sas_loginfo.dw.code <
7106 sizeof(pl_code_str)/sizeof(char*))
7107 code_desc = pl_code_str[sas_loginfo.dw.code];
7108 break;
7109 case 2: /* IR */
7110 if (sas_loginfo.dw.code >=
7111 sizeof(ir_code_str)/sizeof(char*))
7112 break;
7113 code_desc = ir_code_str[sas_loginfo.dw.code];
7114 if (sas_loginfo.dw.subcode >=
7115 sizeof(raid_sub_code_str)/sizeof(char*))
7116 break;
7117 if (sas_loginfo.dw.code == 0)
7118 sub_code_desc =
7119 raid_sub_code_str[sas_loginfo.dw.subcode];
7120 break;
7121 default:
7122 return;
7123 }
7124
7125 if (sub_code_desc != NULL)
7126 printk(MYIOC_s_INFO_FMT
7127 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7128 " SubCode={%s}\n",
7129 ioc->name, log_info, originator_desc, code_desc,
7130 sub_code_desc);
7131 else if (code_desc != NULL)
7132 printk(MYIOC_s_INFO_FMT
7133 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7134 " SubCode(0x%04x)\n",
7135 ioc->name, log_info, originator_desc, code_desc,
7136 sas_loginfo.dw.subcode);
7137 else
7138 printk(MYIOC_s_INFO_FMT
7139 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7140 " SubCode(0x%04x)\n",
7141 ioc->name, log_info, originator_desc,
7142 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7143 }
7144
7145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7146 /**
7147 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7148 * @ioc: Pointer to MPT_ADAPTER structure
7149 * @ioc_status: U32 IOCStatus word from IOC
7150 * @mf: Pointer to MPT request frame
7151 *
7152 * Refer to lsi/mpi.h.
7153 **/
7154 static void
7155 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7156 {
7157 Config_t *pReq = (Config_t *)mf;
7158 char extend_desc[EVENT_DESCR_STR_SZ];
7159 char *desc = NULL;
7160 u32 form;
7161 u8 page_type;
7162
7163 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7164 page_type = pReq->ExtPageType;
7165 else
7166 page_type = pReq->Header.PageType;
7167
7168 /*
7169 * ignore invalid page messages for GET_NEXT_HANDLE
7170 */
7171 form = le32_to_cpu(pReq->PageAddress);
7172 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7173 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7174 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7175 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7176 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7177 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7178 return;
7179 }
7180 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7181 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7182 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7183 return;
7184 }
7185
7186 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7187 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7188 page_type, pReq->Header.PageNumber, pReq->Action, form);
7189
7190 switch (ioc_status) {
7191
7192 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7193 desc = "Config Page Invalid Action";
7194 break;
7195
7196 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7197 desc = "Config Page Invalid Type";
7198 break;
7199
7200 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7201 desc = "Config Page Invalid Page";
7202 break;
7203
7204 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7205 desc = "Config Page Invalid Data";
7206 break;
7207
7208 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7209 desc = "Config Page No Defaults";
7210 break;
7211
7212 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7213 desc = "Config Page Can't Commit";
7214 break;
7215 }
7216
7217 if (!desc)
7218 return;
7219
7220 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7221 ioc->name, ioc_status, desc, extend_desc));
7222 }
7223
7224 /**
7225 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7226 * @ioc: Pointer to MPT_ADAPTER structure
7227 * @ioc_status: U32 IOCStatus word from IOC
7228 * @mf: Pointer to MPT request frame
7229 *
7230 * Refer to lsi/mpi.h.
7231 **/
7232 static void
7233 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7234 {
7235 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7236 char *desc = NULL;
7237
7238 switch (status) {
7239
7240 /****************************************************************************/
7241 /* Common IOCStatus values for all replies */
7242 /****************************************************************************/
7243
7244 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7245 desc = "Invalid Function";
7246 break;
7247
7248 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7249 desc = "Busy";
7250 break;
7251
7252 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7253 desc = "Invalid SGL";
7254 break;
7255
7256 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7257 desc = "Internal Error";
7258 break;
7259
7260 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7261 desc = "Reserved";
7262 break;
7263
7264 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7265 desc = "Insufficient Resources";
7266 break;
7267
7268 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7269 desc = "Invalid Field";
7270 break;
7271
7272 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7273 desc = "Invalid State";
7274 break;
7275
7276 /****************************************************************************/
7277 /* Config IOCStatus values */
7278 /****************************************************************************/
7279
7280 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7281 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7282 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7283 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7284 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7285 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7286 mpt_iocstatus_info_config(ioc, status, mf);
7287 break;
7288
7289 /****************************************************************************/
7290 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7291 /* */
7292 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7293 /* */
7294 /****************************************************************************/
7295
7296 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7297 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7298 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7299 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7300 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7301 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7302 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7303 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7304 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7305 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7306 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7307 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7308 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7309 break;
7310
7311 /****************************************************************************/
7312 /* SCSI Target values */
7313 /****************************************************************************/
7314
7315 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7316 desc = "Target: Priority IO";
7317 break;
7318
7319 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7320 desc = "Target: Invalid Port";
7321 break;
7322
7323 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7324 desc = "Target Invalid IO Index:";
7325 break;
7326
7327 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7328 desc = "Target: Aborted";
7329 break;
7330
7331 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7332 desc = "Target: No Conn Retryable";
7333 break;
7334
7335 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7336 desc = "Target: No Connection";
7337 break;
7338
7339 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7340 desc = "Target: Transfer Count Mismatch";
7341 break;
7342
7343 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7344 desc = "Target: STS Data not Sent";
7345 break;
7346
7347 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7348 desc = "Target: Data Offset Error";
7349 break;
7350
7351 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7352 desc = "Target: Too Much Write Data";
7353 break;
7354
7355 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7356 desc = "Target: IU Too Short";
7357 break;
7358
7359 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7360 desc = "Target: ACK NAK Timeout";
7361 break;
7362
7363 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7364 desc = "Target: Nak Received";
7365 break;
7366
7367 /****************************************************************************/
7368 /* Fibre Channel Direct Access values */
7369 /****************************************************************************/
7370
7371 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7372 desc = "FC: Aborted";
7373 break;
7374
7375 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7376 desc = "FC: RX ID Invalid";
7377 break;
7378
7379 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7380 desc = "FC: DID Invalid";
7381 break;
7382
7383 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7384 desc = "FC: Node Logged Out";
7385 break;
7386
7387 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7388 desc = "FC: Exchange Canceled";
7389 break;
7390
7391 /****************************************************************************/
7392 /* LAN values */
7393 /****************************************************************************/
7394
7395 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7396 desc = "LAN: Device not Found";
7397 break;
7398
7399 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7400 desc = "LAN: Device Failure";
7401 break;
7402
7403 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7404 desc = "LAN: Transmit Error";
7405 break;
7406
7407 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7408 desc = "LAN: Transmit Aborted";
7409 break;
7410
7411 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7412 desc = "LAN: Receive Error";
7413 break;
7414
7415 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7416 desc = "LAN: Receive Aborted";
7417 break;
7418
7419 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7420 desc = "LAN: Partial Packet";
7421 break;
7422
7423 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7424 desc = "LAN: Canceled";
7425 break;
7426
7427 /****************************************************************************/
7428 /* Serial Attached SCSI values */
7429 /****************************************************************************/
7430
7431 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7432 desc = "SAS: SMP Request Failed";
7433 break;
7434
7435 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7436 desc = "SAS: SMP Data Overrun";
7437 break;
7438
7439 default:
7440 desc = "Others";
7441 break;
7442 }
7443
7444 if (!desc)
7445 return;
7446
7447 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7448 ioc->name, status, desc));
7449 }
7450
7451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7452 EXPORT_SYMBOL(mpt_attach);
7453 EXPORT_SYMBOL(mpt_detach);
7454 #ifdef CONFIG_PM
7455 EXPORT_SYMBOL(mpt_resume);
7456 EXPORT_SYMBOL(mpt_suspend);
7457 #endif
7458 EXPORT_SYMBOL(ioc_list);
7459 EXPORT_SYMBOL(mpt_proc_root_dir);
7460 EXPORT_SYMBOL(mpt_register);
7461 EXPORT_SYMBOL(mpt_deregister);
7462 EXPORT_SYMBOL(mpt_event_register);
7463 EXPORT_SYMBOL(mpt_event_deregister);
7464 EXPORT_SYMBOL(mpt_reset_register);
7465 EXPORT_SYMBOL(mpt_reset_deregister);
7466 EXPORT_SYMBOL(mpt_device_driver_register);
7467 EXPORT_SYMBOL(mpt_device_driver_deregister);
7468 EXPORT_SYMBOL(mpt_get_msg_frame);
7469 EXPORT_SYMBOL(mpt_put_msg_frame);
7470 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7471 EXPORT_SYMBOL(mpt_free_msg_frame);
7472 EXPORT_SYMBOL(mpt_add_sge);
7473 EXPORT_SYMBOL(mpt_send_handshake_request);
7474 EXPORT_SYMBOL(mpt_verify_adapter);
7475 EXPORT_SYMBOL(mpt_GetIocState);
7476 EXPORT_SYMBOL(mpt_print_ioc_summary);
7477 EXPORT_SYMBOL(mpt_HardResetHandler);
7478 EXPORT_SYMBOL(mpt_config);
7479 EXPORT_SYMBOL(mpt_findImVolumes);
7480 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7481 EXPORT_SYMBOL(mpt_free_fw_memory);
7482 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7483 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7484
7485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7486 /**
7487 * fusion_init - Fusion MPT base driver initialization routine.
7488 *
7489 * Returns 0 for success, non-zero for failure.
7490 */
7491 static int __init
7492 fusion_init(void)
7493 {
7494 u8 cb_idx;
7495
7496 show_mptmod_ver(my_NAME, my_VERSION);
7497 printk(KERN_INFO COPYRIGHT "\n");
7498
7499 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7500 MptCallbacks[cb_idx] = NULL;
7501 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7502 MptEvHandlers[cb_idx] = NULL;
7503 MptResetHandlers[cb_idx] = NULL;
7504 }
7505
7506 /* Register ourselves (mptbase) in order to facilitate
7507 * EventNotification handling.
7508 */
7509 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7510
7511 /* Register for hard reset handling callbacks.
7512 */
7513 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7514
7515 #ifdef CONFIG_PROC_FS
7516 (void) procmpt_create();
7517 #endif
7518 return 0;
7519 }
7520
7521 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7522 /**
7523 * fusion_exit - Perform driver unload cleanup.
7524 *
7525 * This routine frees all resources associated with each MPT adapter
7526 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7527 */
7528 static void __exit
7529 fusion_exit(void)
7530 {
7531
7532 mpt_reset_deregister(mpt_base_index);
7533
7534 #ifdef CONFIG_PROC_FS
7535 procmpt_destroy();
7536 #endif
7537 }
7538
7539 module_init(fusion_init);
7540 module_exit(fusion_exit);