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