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.
8 * Copyright (c) 1999-2005 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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.
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.
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.
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
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
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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>
67 #include <asm/irq.h> /* needed for __irq_itoa() proto */
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
73 #define my_NAME "Fusion MPT base driver"
74 #define my_VERSION MPT_LINUX_VERSION_COMMON
75 #define MYNAM "mptbase"
77 MODULE_AUTHOR(MODULEAUTHOR);
78 MODULE_DESCRIPTION(my_NAME);
79 MODULE_LICENSE("GPL");
85 static int mfcounter = 0;
86 #define PRINT_MF_COUNT 20000
89 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
93 int mpt_lan_index = -1;
94 int mpt_stm_index = -1;
96 struct proc_dir_entry *mpt_proc_root_dir;
98 #define WHOINIT_UNKNOWN 0xAA
100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
104 /* Adapter link list */
106 /* Callback lookup table */
107 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
108 /* Protocol driver class lookup table */
109 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
110 /* Event handler lookup table */
111 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
112 /* Reset handler lookup table */
113 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
114 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
116 static int mpt_base_index = -1;
117 static int last_drv_idx = -1;
119 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
121 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
125 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
126 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
127 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
128 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
130 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
131 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
132 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
133 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
135 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
136 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
137 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
138 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
139 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
140 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
141 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
142 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
143 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
144 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
145 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
146 static int PrimeIocFifos(MPT_ADAPTER *ioc);
147 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
148 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
149 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
150 static int GetLanConfigPages(MPT_ADAPTER *ioc);
151 static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
152 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
153 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
154 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
155 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
156 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
157 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
158 static void mpt_timer_expired(unsigned long data);
159 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
160 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
161 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
162 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
164 #ifdef CONFIG_PROC_FS
165 static int procmpt_summary_read(char *buf, char **start, off_t offset,
166 int request, int *eof, void *data);
167 static int procmpt_version_read(char *buf, char **start, off_t offset,
168 int request, int *eof, void *data);
169 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
170 int request, int *eof, void *data);
172 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
174 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
175 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
176 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
177 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
178 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
179 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
181 /* module entry point */
182 static int __init fusion_init (void);
183 static void __exit fusion_exit (void);
185 #define CHIPREG_READ32(addr) readl_relaxed(addr)
186 #define CHIPREG_READ32_dmasync(addr) readl(addr)
187 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
188 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
189 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
192 pci_disable_io_access(struct pci_dev *pdev)
196 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
198 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
202 pci_enable_io_access(struct pci_dev *pdev)
206 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
208 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
212 * Process turbo (context) reply...
215 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
217 MPT_FRAME_HDR *mf = NULL;
218 MPT_FRAME_HDR *mr = NULL;
222 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
225 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
226 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
227 req_idx = pa & 0x0000FFFF;
228 cb_idx = (pa & 0x00FF0000) >> 16;
229 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
231 case MPI_CONTEXT_REPLY_TYPE_LAN:
232 cb_idx = mpt_lan_index;
234 * Blind set of mf to NULL here was fatal
235 * after lan_reply says "freeme"
236 * Fix sort of combined with an optimization here;
237 * added explicit check for case where lan_reply
238 * was just returning 1 and doing nothing else.
239 * For this case skip the callback, but set up
240 * proper mf value first here:-)
242 if ((pa & 0x58000000) == 0x58000000) {
243 req_idx = pa & 0x0000FFFF;
244 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
245 mpt_free_msg_frame(ioc, mf);
250 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
252 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
253 cb_idx = mpt_stm_index;
254 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
261 /* Check for (valid) IO callback! */
262 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
263 MptCallbacks[cb_idx] == NULL) {
264 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
265 __FUNCTION__, ioc->name, cb_idx);
269 if (MptCallbacks[cb_idx](ioc, mf, mr))
270 mpt_free_msg_frame(ioc, mf);
276 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
287 /* non-TURBO reply! Hmmm, something may be up...
288 * Newest turbo reply mechanism; get address
289 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
292 /* Map DMA address of reply header to cpu address.
293 * pa is 32 bits - but the dma address may be 32 or 64 bits
294 * get offset based only only the low addresses
297 reply_dma_low = (pa <<= 1);
298 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
299 (reply_dma_low - ioc->reply_frames_low_dma));
301 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
302 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
303 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
305 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
306 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
307 DBG_DUMP_REPLY_FRAME(mr)
309 /* Check/log IOC log info
311 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
312 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
313 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
314 if (ioc->bus_type == FC)
315 mpt_fc_log_info(ioc, log_info);
316 else if (ioc->bus_type == SCSI)
317 mpt_sp_log_info(ioc, log_info);
318 else if (ioc->bus_type == SAS)
319 mpt_sas_log_info(ioc, log_info);
321 if (ioc_stat & MPI_IOCSTATUS_MASK) {
322 if (ioc->bus_type == SCSI &&
323 cb_idx != mpt_stm_index &&
324 cb_idx != mpt_lan_index)
325 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
329 /* Check for (valid) IO callback! */
330 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
331 MptCallbacks[cb_idx] == NULL) {
332 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
333 __FUNCTION__, ioc->name, cb_idx);
338 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
341 /* Flush (non-TURBO) reply with a WRITE! */
342 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
345 mpt_free_msg_frame(ioc, mf);
349 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
351 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
352 * @irq: irq number (not used)
353 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
354 * @r: pt_regs pointer (not used)
356 * This routine is registered via the request_irq() kernel API call,
357 * and handles all interrupts generated from a specific MPT adapter
358 * (also referred to as a IO Controller or IOC).
359 * This routine must clear the interrupt from the adapter and does
360 * so by reading the reply FIFO. Multiple replies may be processed
361 * per single call to this routine.
363 * This routine handles register-level access of the adapter but
364 * dispatches (calls) a protocol-specific callback routine to handle
365 * the protocol-specific details of the MPT request completion.
368 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
370 MPT_ADAPTER *ioc = bus_id;
374 * Drain the reply FIFO!
377 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
378 if (pa == 0xFFFFFFFF)
380 else if (pa & MPI_ADDRESS_REPLY_A_BIT)
383 mpt_turbo_reply(ioc, pa);
389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
391 * mpt_base_reply - MPT base driver's callback routine; all base driver
392 * "internal" request/reply processing is routed here.
393 * Currently used for EventNotification and EventAck handling.
394 * @ioc: Pointer to MPT_ADAPTER structure
395 * @mf: Pointer to original MPT request frame
396 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
398 * Returns 1 indicating original alloc'd request frame ptr
399 * should be freed, or 0 if it shouldn't.
402 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
407 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
409 #if defined(MPT_DEBUG_MSG_FRAME)
410 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
411 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
412 DBG_DUMP_REQUEST_FRAME_HDR(mf)
416 func = reply->u.hdr.Function;
417 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
420 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
421 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
425 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
426 if (results != evHandlers) {
427 /* CHECKME! Any special handling needed here? */
428 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
429 ioc->name, evHandlers, results));
433 * Hmmm... It seems that EventNotificationReply is an exception
434 * to the rule of one reply per request.
436 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
438 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
439 ioc->name, pEvReply));
441 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
442 ioc->name, pEvReply));
445 #ifdef CONFIG_PROC_FS
446 // LogEvent(ioc, pEvReply);
449 } else if (func == MPI_FUNCTION_EVENT_ACK) {
450 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
452 } else if (func == MPI_FUNCTION_CONFIG ||
453 func == MPI_FUNCTION_TOOLBOX) {
457 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
458 ioc->name, mf, reply));
460 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
463 /* disable timer and remove from linked list */
464 del_timer(&pCfg->timer);
466 spin_lock_irqsave(&ioc->FreeQlock, flags);
467 list_del(&pCfg->linkage);
468 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
471 * If IOC Status is SUCCESS, save the header
472 * and set the status code to GOOD.
474 pCfg->status = MPT_CONFIG_ERROR;
476 ConfigReply_t *pReply = (ConfigReply_t *)reply;
479 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
480 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
481 status, le32_to_cpu(pReply->IOCLogInfo)));
483 pCfg->status = status;
484 if (status == MPI_IOCSTATUS_SUCCESS) {
485 if ((pReply->Header.PageType &
486 MPI_CONFIG_PAGETYPE_MASK) ==
487 MPI_CONFIG_PAGETYPE_EXTENDED) {
488 pCfg->cfghdr.ehdr->ExtPageLength =
489 le16_to_cpu(pReply->ExtPageLength);
490 pCfg->cfghdr.ehdr->ExtPageType =
493 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
495 /* If this is a regular header, save PageLength. */
496 /* LMP Do this better so not using a reserved field! */
497 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
498 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
499 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
504 * Wake up the original calling thread
509 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
510 /* we should be always getting a reply frame */
511 memcpy(ioc->persist_reply_frame, reply,
512 min(MPT_DEFAULT_FRAME_SIZE,
513 4*reply->u.reply.MsgLength));
514 del_timer(&ioc->persist_timer);
515 ioc->persist_wait_done = 1;
518 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
523 * Conditionally tell caller to free the original
524 * EventNotification/EventAck/unexpected request frame!
529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
531 * mpt_register - Register protocol-specific main callback handler.
532 * @cbfunc: callback function pointer
533 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
535 * This routine is called by a protocol-specific driver (SCSI host,
536 * LAN, SCSI target) to register it's reply callback routine. Each
537 * protocol-specific driver must do this before it will be able to
538 * use any IOC resources, such as obtaining request frames.
540 * NOTES: The SCSI protocol driver currently calls this routine thrice
541 * in order to register separate callbacks; one for "normal" SCSI IO;
542 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
544 * Returns a positive integer valued "handle" in the
545 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
546 * Any non-positive return value (including zero!) should be considered
547 * an error by the caller.
550 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
557 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
558 * (slot/handle 0 is reserved!)
560 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
561 if (MptCallbacks[i] == NULL) {
562 MptCallbacks[i] = cbfunc;
563 MptDriverClass[i] = dclass;
564 MptEvHandlers[i] = NULL;
573 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
575 * mpt_deregister - Deregister a protocol drivers resources.
576 * @cb_idx: previously registered callback handle
578 * Each protocol-specific driver should call this routine when it's
579 * module is unloaded.
582 mpt_deregister(int cb_idx)
584 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
585 MptCallbacks[cb_idx] = NULL;
586 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
587 MptEvHandlers[cb_idx] = NULL;
593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
595 * mpt_event_register - Register protocol-specific event callback
597 * @cb_idx: previously registered (via mpt_register) callback handle
598 * @ev_cbfunc: callback function
600 * This routine can be called by one or more protocol-specific drivers
601 * if/when they choose to be notified of MPT events.
603 * Returns 0 for success.
606 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
608 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
611 MptEvHandlers[cb_idx] = ev_cbfunc;
615 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
617 * mpt_event_deregister - Deregister protocol-specific event callback
619 * @cb_idx: previously registered callback handle
621 * Each protocol-specific driver should call this routine
622 * when it does not (or can no longer) handle events,
623 * or when it's module is unloaded.
626 mpt_event_deregister(int cb_idx)
628 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
631 MptEvHandlers[cb_idx] = NULL;
634 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
636 * mpt_reset_register - Register protocol-specific IOC reset handler.
637 * @cb_idx: previously registered (via mpt_register) callback handle
638 * @reset_func: reset function
640 * This routine can be called by one or more protocol-specific drivers
641 * if/when they choose to be notified of IOC resets.
643 * Returns 0 for success.
646 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
648 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
651 MptResetHandlers[cb_idx] = reset_func;
655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
657 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
658 * @cb_idx: previously registered callback handle
660 * Each protocol-specific driver should call this routine
661 * when it does not (or can no longer) handle IOC reset handling,
662 * or when it's module is unloaded.
665 mpt_reset_deregister(int cb_idx)
667 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
670 MptResetHandlers[cb_idx] = NULL;
673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
675 * mpt_device_driver_register - Register device driver hooks
678 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
682 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
686 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
688 /* call per pci device probe entry point */
689 list_for_each_entry(ioc, &ioc_list, list) {
690 if(dd_cbfunc->probe) {
691 dd_cbfunc->probe(ioc->pcidev,
692 ioc->pcidev->driver->id_table);
699 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
701 * mpt_device_driver_deregister - DeRegister device driver hooks
704 mpt_device_driver_deregister(int cb_idx)
706 struct mpt_pci_driver *dd_cbfunc;
709 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
712 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
714 list_for_each_entry(ioc, &ioc_list, list) {
715 if (dd_cbfunc->remove)
716 dd_cbfunc->remove(ioc->pcidev);
719 MptDeviceDriverHandlers[cb_idx] = NULL;
723 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
725 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
726 * allocated per MPT adapter.
727 * @handle: Handle of registered MPT protocol driver
728 * @ioc: Pointer to MPT adapter structure
730 * Returns pointer to a MPT request frame or %NULL if none are available
731 * or IOC is not active.
734 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
738 u16 req_idx; /* Request index */
740 /* validate handle and ioc identifier */
744 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
747 /* If interrupts are not attached, do not return a request frame */
751 spin_lock_irqsave(&ioc->FreeQlock, flags);
752 if (!list_empty(&ioc->FreeQ)) {
755 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
756 u.frame.linkage.list);
757 list_del(&mf->u.frame.linkage.list);
758 mf->u.frame.linkage.arg1 = 0;
759 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
760 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
762 req_idx = req_offset / ioc->req_sz;
763 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
764 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
765 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
772 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
776 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
778 if (mfcounter == PRINT_MF_COUNT)
779 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
782 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
783 ioc->name, handle, ioc->id, mf));
787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
789 * mpt_put_msg_frame - Send a protocol specific MPT request frame
791 * @handle: Handle of registered MPT protocol driver
792 * @ioc: Pointer to MPT adapter structure
793 * @mf: Pointer to MPT request frame
795 * This routine posts a MPT request frame to the request post FIFO of a
796 * specific MPT adapter.
799 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
803 u16 req_idx; /* Request index */
805 /* ensure values are reset properly! */
806 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
807 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
809 req_idx = req_offset / ioc->req_sz;
810 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
811 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
813 #ifdef MPT_DEBUG_MSG_FRAME
815 u32 *m = mf->u.frame.hwhdr.__hdr;
818 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
820 n = ioc->req_sz/4 - 1;
823 for (ii=0; ii<=n; ii++) {
824 if (ii && ((ii%8)==0))
825 printk("\n" KERN_INFO " ");
826 printk(" %08x", le32_to_cpu(m[ii]));
832 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
833 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]));
834 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
837 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
839 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
840 * @handle: Handle of registered MPT protocol driver
841 * @ioc: Pointer to MPT adapter structure
842 * @mf: Pointer to MPT request frame
844 * This routine places a MPT request frame back on the MPT adapter's
848 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
852 /* Put Request back on FreeQ! */
853 spin_lock_irqsave(&ioc->FreeQlock, flags);
854 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
855 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
859 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
864 * mpt_add_sge - Place a simple SGE at address pAddr.
865 * @pAddr: virtual address for SGE
866 * @flagslength: SGE flags and data transfer length
867 * @dma_addr: Physical address
869 * This routine places a MPT request frame back on the MPT adapter's
873 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
875 if (sizeof(dma_addr_t) == sizeof(u64)) {
876 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
877 u32 tmp = dma_addr & 0xFFFFFFFF;
879 pSge->FlagsLength = cpu_to_le32(flagslength);
880 pSge->Address.Low = cpu_to_le32(tmp);
881 tmp = (u32) ((u64)dma_addr >> 32);
882 pSge->Address.High = cpu_to_le32(tmp);
885 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
886 pSge->FlagsLength = cpu_to_le32(flagslength);
887 pSge->Address = cpu_to_le32(dma_addr);
891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
893 * mpt_send_handshake_request - Send MPT request via doorbell
895 * @handle: Handle of registered MPT protocol driver
896 * @ioc: Pointer to MPT adapter structure
897 * @reqBytes: Size of the request in bytes
898 * @req: Pointer to MPT request frame
899 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
901 * This routine is used exclusively to send MptScsiTaskMgmt
902 * requests since they are required to be sent via doorbell handshake.
904 * NOTE: It is the callers responsibility to byte-swap fields in the
905 * request which are greater than 1 byte in size.
907 * Returns 0 for success, non-zero for failure.
910 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
916 /* State is known to be good upon entering
917 * this function so issue the bus reset
922 * Emulate what mpt_put_msg_frame() does /wrt to sanity
923 * setting cb_idx/req_idx. But ONLY if this request
924 * is in proper (pre-alloc'd) request buffer range...
926 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
927 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
928 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
929 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
930 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
933 /* Make sure there are no doorbells */
934 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
936 CHIPREG_WRITE32(&ioc->chip->Doorbell,
937 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
938 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
940 /* Wait for IOC doorbell int */
941 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
945 /* Read doorbell and check for active bit */
946 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
949 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
952 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
954 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
958 /* Send request via doorbell handshake */
959 req_as_bytes = (u8 *) req;
960 for (ii = 0; ii < reqBytes/4; ii++) {
963 word = ((req_as_bytes[(ii*4) + 0] << 0) |
964 (req_as_bytes[(ii*4) + 1] << 8) |
965 (req_as_bytes[(ii*4) + 2] << 16) |
966 (req_as_bytes[(ii*4) + 3] << 24));
967 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
968 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
974 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
979 /* Make sure there are no doorbells */
980 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
985 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
987 * mpt_host_page_access_control - provides mechanism for the host
988 * driver to control the IOC's Host Page Buffer access.
989 * @ioc: Pointer to MPT adapter structure
990 * @access_control_value: define bits below
992 * Access Control Value - bits[15:12]
994 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
995 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
996 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
998 * Returns 0 for success, non-zero for failure.
1002 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1006 /* return if in use */
1007 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1008 & MPI_DOORBELL_ACTIVE)
1011 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1013 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1014 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1015 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1016 (access_control_value<<12)));
1018 /* Wait for IOC to clear Doorbell Status bit */
1019 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1025 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1027 * mpt_host_page_alloc - allocate system memory for the fw
1028 * If we already allocated memory in past, then resend the same pointer.
1029 * ioc@: Pointer to pointer to IOC adapter
1030 * ioc_init@: Pointer to ioc init config page
1032 * Returns 0 for success, non-zero for failure.
1035 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1039 u32 host_page_buffer_sz=0;
1041 if(!ioc->HostPageBuffer) {
1043 host_page_buffer_sz =
1044 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1046 if(!host_page_buffer_sz)
1047 return 0; /* fw doesn't need any host buffers */
1049 /* spin till we get enough memory */
1050 while(host_page_buffer_sz > 0) {
1052 if((ioc->HostPageBuffer = pci_alloc_consistent(
1054 host_page_buffer_sz,
1055 &ioc->HostPageBuffer_dma)) != NULL) {
1057 dinitprintk((MYIOC_s_INFO_FMT
1058 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1060 ioc->HostPageBuffer,
1061 ioc->HostPageBuffer_dma,
1062 host_page_buffer_sz));
1063 ioc->alloc_total += host_page_buffer_sz;
1064 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1068 host_page_buffer_sz -= (4*1024);
1072 if(!ioc->HostPageBuffer) {
1073 printk(MYIOC_s_ERR_FMT
1074 "Failed to alloc memory for host_page_buffer!\n",
1079 psge = (char *)&ioc_init->HostPageBufferSGE;
1080 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1081 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1082 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1083 MPI_SGE_FLAGS_HOST_TO_IOC |
1084 MPI_SGE_FLAGS_END_OF_BUFFER;
1085 if (sizeof(dma_addr_t) == sizeof(u64)) {
1086 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1088 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1089 flags_length |= ioc->HostPageBuffer_sz;
1090 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1091 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1098 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1099 * the associated MPT adapter structure.
1100 * @iocid: IOC unique identifier (integer)
1101 * @iocpp: Pointer to pointer to IOC adapter
1103 * Returns iocid and sets iocpp.
1106 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1110 list_for_each_entry(ioc,&ioc_list,list) {
1111 if (ioc->id == iocid) {
1121 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1123 * mpt_attach - Install a PCI intelligent MPT adapter.
1124 * @pdev: Pointer to pci_dev structure
1126 * This routine performs all the steps necessary to bring the IOC of
1127 * a MPT adapter to a OPERATIONAL state. This includes registering
1128 * memory regions, registering the interrupt, and allocating request
1129 * and reply memory pools.
1131 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1134 * Returns 0 for success, non-zero for failure.
1136 * TODO: Add support for polled controllers
1139 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1143 unsigned long mem_phys;
1151 static int mpt_ids = 0;
1152 #ifdef CONFIG_PROC_FS
1153 struct proc_dir_entry *dent, *ent;
1156 if (pci_enable_device(pdev))
1159 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1161 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1162 dprintk((KERN_INFO MYNAM
1163 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1164 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1165 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1169 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1170 dprintk((KERN_INFO MYNAM
1171 ": Using 64 bit consistent mask\n"));
1173 dprintk((KERN_INFO MYNAM
1174 ": Not using 64 bit consistent mask\n"));
1176 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1178 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1181 memset(ioc, 0, sizeof(MPT_ADAPTER));
1182 ioc->alloc_total = sizeof(MPT_ADAPTER);
1183 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1184 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1187 ioc->diagPending = 0;
1188 spin_lock_init(&ioc->diagLock);
1190 /* Initialize the event logging.
1192 ioc->eventTypes = 0; /* None */
1193 ioc->eventContext = 0;
1194 ioc->eventLogSize = 0;
1201 ioc->cached_fw = NULL;
1203 /* Initilize SCSI Config Data structure
1205 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1207 /* Initialize the running configQ head.
1209 INIT_LIST_HEAD(&ioc->configQ);
1211 /* Find lookup slot. */
1212 INIT_LIST_HEAD(&ioc->list);
1213 ioc->id = mpt_ids++;
1215 mem_phys = msize = 0;
1217 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1218 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1219 /* Get I/O space! */
1220 port = pci_resource_start(pdev, ii);
1221 psize = pci_resource_len(pdev,ii);
1224 mem_phys = pci_resource_start(pdev, ii);
1225 msize = pci_resource_len(pdev,ii);
1229 ioc->mem_size = msize;
1231 if (ii == DEVICE_COUNT_RESOURCE) {
1232 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1237 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1238 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1241 /* Get logical ptr for PciMem0 space */
1242 /*mem = ioremap(mem_phys, msize);*/
1243 mem = ioremap(mem_phys, 0x100);
1245 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1250 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1252 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1253 &ioc->facts, &ioc->pfacts[0]));
1255 ioc->mem_phys = mem_phys;
1256 ioc->chip = (SYSIF_REGS __iomem *)mem;
1258 /* Save Port IO values in case we need to do downloadboot */
1260 u8 *pmem = (u8*)port;
1261 ioc->pio_mem_phys = port;
1262 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1265 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1266 ioc->prod_name = "LSIFC909";
1269 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1270 ioc->prod_name = "LSIFC929";
1273 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1274 ioc->prod_name = "LSIFC919";
1277 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1278 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1280 if (revision < XL_929) {
1281 ioc->prod_name = "LSIFC929X";
1282 /* 929X Chip Fix. Set Split transactions level
1283 * for PCIX. Set MOST bits to zero.
1285 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1287 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1289 ioc->prod_name = "LSIFC929XL";
1290 /* 929XL Chip Fix. Set MMRBC to 0x08.
1292 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1294 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1297 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1298 ioc->prod_name = "LSIFC919X";
1300 /* 919X Chip Fix. Set Split transactions level
1301 * for PCIX. Set MOST bits to zero.
1303 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1305 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1307 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1308 ioc->prod_name = "LSIFC939X";
1310 ioc->errata_flag_1064 = 1;
1312 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1313 ioc->prod_name = "LSIFC949X";
1315 ioc->errata_flag_1064 = 1;
1317 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1318 ioc->prod_name = "LSI53C1030";
1319 ioc->bus_type = SCSI;
1320 /* 1030 Chip Fix. Disable Split transactions
1321 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1323 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1324 if (revision < C0_1030) {
1325 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1327 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1330 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1331 ioc->prod_name = "LSI53C1035";
1332 ioc->bus_type = SCSI;
1334 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1335 ioc->prod_name = "LSISAS1064";
1336 ioc->bus_type = SAS;
1337 ioc->errata_flag_1064 = 1;
1339 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
1340 ioc->prod_name = "LSISAS1066";
1341 ioc->bus_type = SAS;
1342 ioc->errata_flag_1064 = 1;
1344 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1345 ioc->prod_name = "LSISAS1068";
1346 ioc->bus_type = SAS;
1347 ioc->errata_flag_1064 = 1;
1349 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1350 ioc->prod_name = "LSISAS1064E";
1351 ioc->bus_type = SAS;
1353 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
1354 ioc->prod_name = "LSISAS1066E";
1355 ioc->bus_type = SAS;
1357 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1358 ioc->prod_name = "LSISAS1068E";
1359 ioc->bus_type = SAS;
1362 if (ioc->errata_flag_1064)
1363 pci_disable_io_access(pdev);
1365 sprintf(ioc->name, "ioc%d", ioc->id);
1367 spin_lock_init(&ioc->FreeQlock);
1370 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1372 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1374 /* Set lookup ptr. */
1375 list_add_tail(&ioc->list, &ioc_list);
1379 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1383 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1384 ioc->name, pdev->irq);
1386 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1387 ioc->name, __irq_itoa(pdev->irq));
1389 list_del(&ioc->list);
1395 ioc->pci_irq = pdev->irq;
1397 pci_set_master(pdev); /* ?? */
1398 pci_set_drvdata(pdev, ioc);
1401 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1403 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1407 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1409 mpt_detect_bound_ports(ioc, pdev);
1411 if ((r = mpt_do_ioc_recovery(ioc,
1412 MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1413 printk(KERN_WARNING MYNAM
1414 ": WARNING - %s did not initialize properly! (%d)\n",
1417 list_del(&ioc->list);
1418 free_irq(ioc->pci_irq, ioc);
1421 pci_set_drvdata(pdev, NULL);
1425 /* call per device driver probe entry point */
1426 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1427 if(MptDeviceDriverHandlers[ii] &&
1428 MptDeviceDriverHandlers[ii]->probe) {
1429 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1433 #ifdef CONFIG_PROC_FS
1435 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1437 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1439 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1441 ent->read_proc = procmpt_iocinfo_read;
1444 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1446 ent->read_proc = procmpt_summary_read;
1455 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1457 * mpt_detach - Remove a PCI intelligent MPT adapter.
1458 * @pdev: Pointer to pci_dev structure
1463 mpt_detach(struct pci_dev *pdev)
1465 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1469 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1470 remove_proc_entry(pname, NULL);
1471 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1472 remove_proc_entry(pname, NULL);
1473 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1474 remove_proc_entry(pname, NULL);
1476 /* call per device driver remove entry point */
1477 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1478 if(MptDeviceDriverHandlers[ii] &&
1479 MptDeviceDriverHandlers[ii]->remove) {
1480 MptDeviceDriverHandlers[ii]->remove(pdev);
1484 /* Disable interrupts! */
1485 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1488 synchronize_irq(pdev->irq);
1490 /* Clear any lingering interrupt */
1491 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1493 CHIPREG_READ32(&ioc->chip->IntStatus);
1495 mpt_adapter_dispose(ioc);
1497 pci_set_drvdata(pdev, NULL);
1500 /**************************************************************************
1504 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1506 * mpt_suspend - Fusion MPT base driver suspend routine.
1511 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1514 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1516 device_state=pci_choose_state(pdev, state);
1518 printk(MYIOC_s_INFO_FMT
1519 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1520 ioc->name, pdev, pci_name(pdev), device_state);
1522 pci_save_state(pdev);
1524 /* put ioc into READY_STATE */
1525 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1526 printk(MYIOC_s_ERR_FMT
1527 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1530 /* disable interrupts */
1531 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1534 /* Clear any lingering interrupt */
1535 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1537 pci_disable_device(pdev);
1538 pci_set_power_state(pdev, device_state);
1543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1545 * mpt_resume - Fusion MPT base driver resume routine.
1550 mpt_resume(struct pci_dev *pdev)
1552 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1553 u32 device_state = pdev->current_state;
1557 printk(MYIOC_s_INFO_FMT
1558 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1559 ioc->name, pdev, pci_name(pdev), device_state);
1561 pci_set_power_state(pdev, 0);
1562 pci_restore_state(pdev);
1563 pci_enable_device(pdev);
1565 /* enable interrupts */
1566 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1569 /* F/W not running */
1570 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1571 /* enable domain validation flags */
1572 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1573 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1577 printk(MYIOC_s_INFO_FMT
1578 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1580 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1581 CHIPREG_READ32(&ioc->chip->Doorbell));
1583 /* bring ioc to operational state */
1584 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1585 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1586 printk(MYIOC_s_INFO_FMT
1587 "pci-resume: Cannot recover, error:[%x]\n",
1588 ioc->name, recovery_state);
1590 printk(MYIOC_s_INFO_FMT
1591 "pci-resume: success\n", ioc->name);
1598 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1600 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1601 * @ioc: Pointer to MPT adapter structure
1602 * @reason: Event word / reason
1603 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1605 * This routine performs all the steps necessary to bring the IOC
1606 * to a OPERATIONAL state.
1608 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1613 * -1 if failed to get board READY
1614 * -2 if READY but IOCFacts Failed
1615 * -3 if READY but PrimeIOCFifos Failed
1616 * -4 if READY but IOCInit Failed
1619 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1621 int hard_reset_done = 0;
1622 int alt_ioc_ready = 0;
1628 int reset_alt_ioc_active = 0;
1630 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1631 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1633 /* Disable reply interrupts (also blocks FreeQ) */
1634 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1638 if (ioc->alt_ioc->active)
1639 reset_alt_ioc_active = 1;
1641 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1642 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1643 ioc->alt_ioc->active = 0;
1647 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1650 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1651 if (hard_reset_done == -4) {
1652 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1655 if (reset_alt_ioc_active && ioc->alt_ioc) {
1656 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1657 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1658 ioc->alt_ioc->name));
1659 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1660 ioc->alt_ioc->active = 1;
1664 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1670 /* hard_reset_done = 0 if a soft reset was performed
1671 * and 1 if a hard reset was performed.
1673 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1674 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1677 printk(KERN_WARNING MYNAM
1678 ": alt-%s: Not ready WARNING!\n",
1679 ioc->alt_ioc->name);
1682 for (ii=0; ii<5; ii++) {
1683 /* Get IOC facts! Allow 5 retries */
1684 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1690 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1692 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1693 MptDisplayIocCapabilities(ioc);
1696 if (alt_ioc_ready) {
1697 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1698 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1699 /* Retry - alt IOC was initialized once
1701 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1704 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1706 reset_alt_ioc_active = 0;
1707 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1708 MptDisplayIocCapabilities(ioc->alt_ioc);
1712 /* Prime reply & request queues!
1713 * (mucho alloc's) Must be done prior to
1714 * init as upper addresses are needed for init.
1715 * If fails, continue with alt-ioc processing
1717 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1720 /* May need to check/upload firmware & data here!
1721 * If fails, continue with alt-ioc processing
1723 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1726 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1727 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1728 ioc->alt_ioc->name, rc);
1730 reset_alt_ioc_active = 0;
1733 if (alt_ioc_ready) {
1734 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1736 reset_alt_ioc_active = 0;
1737 printk(KERN_WARNING MYNAM
1738 ": alt-%s: (%d) init failure WARNING!\n",
1739 ioc->alt_ioc->name, rc);
1743 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1744 if (ioc->upload_fw) {
1745 ddlprintk((MYIOC_s_INFO_FMT
1746 "firmware upload required!\n", ioc->name));
1748 /* Controller is not operational, cannot do upload
1751 rc = mpt_do_upload(ioc, sleepFlag);
1753 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1755 * Maintain only one pointer to FW memory
1756 * so there will not be two attempt to
1757 * downloadboot onboard dual function
1758 * chips (mpt_adapter_disable,
1761 ioc->cached_fw = NULL;
1762 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1763 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1766 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1774 /* Enable! (reply interrupt) */
1775 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1779 if (reset_alt_ioc_active && ioc->alt_ioc) {
1780 /* (re)Enable alt-IOC! (reply interrupt) */
1781 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1782 ioc->alt_ioc->name));
1783 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1784 ioc->alt_ioc->active = 1;
1787 /* Enable MPT base driver management of EventNotification
1788 * and EventAck handling.
1790 if ((ret == 0) && (!ioc->facts.EventState))
1791 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1793 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1794 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1796 /* Add additional "reason" check before call to GetLanConfigPages
1797 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1798 * recursive scenario; GetLanConfigPages times out, timer expired
1799 * routine calls HardResetHandler, which calls into here again,
1800 * and we try GetLanConfigPages again...
1802 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1803 if (ioc->bus_type == SAS) {
1805 /* clear persistency table */
1806 if(ioc->facts.IOCExceptions &
1807 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1808 ret = mptbase_sas_persist_operation(ioc,
1809 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1816 mpt_findImVolumes(ioc);
1818 } else if (ioc->bus_type == FC) {
1820 * Pre-fetch FC port WWN and stuff...
1821 * (FCPortPage0_t stuff)
1823 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1824 (void) GetFcPortPage0(ioc, ii);
1827 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1828 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1830 * Pre-fetch the ports LAN MAC address!
1831 * (LANPage1_t stuff)
1833 (void) GetLanConfigPages(ioc);
1836 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1837 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1838 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1843 /* Get NVRAM and adapter maximums from SPP 0 and 2
1845 mpt_GetScsiPortSettings(ioc, 0);
1847 /* Get version and length of SDP 1
1849 mpt_readScsiDevicePageHeaders(ioc, 0);
1853 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1854 mpt_findImVolumes(ioc);
1856 /* Check, and possibly reset, the coalescing value
1858 mpt_read_ioc_pg_1(ioc);
1860 mpt_read_ioc_pg_4(ioc);
1863 GetIoUnitPage2(ioc);
1867 * Call each currently registered protocol IOC reset handler
1868 * with post-reset indication.
1869 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1870 * MptResetHandlers[] registered yet.
1872 if (hard_reset_done) {
1874 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1875 if ((ret == 0) && MptResetHandlers[ii]) {
1876 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1878 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1882 if (alt_ioc_ready && MptResetHandlers[ii]) {
1883 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1884 ioc->name, ioc->alt_ioc->name, ii));
1885 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1889 /* FIXME? Examine results here? */
1895 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1897 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1898 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1899 * 929X, 1030 or 1035.
1900 * @ioc: Pointer to MPT adapter structure
1901 * @pdev: Pointer to (struct pci_dev) structure
1903 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1904 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1907 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1909 struct pci_dev *peer=NULL;
1910 unsigned int slot = PCI_SLOT(pdev->devfn);
1911 unsigned int func = PCI_FUNC(pdev->devfn);
1912 MPT_ADAPTER *ioc_srch;
1914 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1915 " searching for devfn match on %x or %x\n",
1916 ioc->name, pci_name(pdev), pdev->bus->number,
1917 pdev->devfn, func-1, func+1));
1919 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1921 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1926 list_for_each_entry(ioc_srch, &ioc_list, list) {
1927 struct pci_dev *_pcidev = ioc_srch->pcidev;
1928 if (_pcidev == peer) {
1929 /* Paranoia checks */
1930 if (ioc->alt_ioc != NULL) {
1931 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1932 ioc->name, ioc->alt_ioc->name);
1934 } else if (ioc_srch->alt_ioc != NULL) {
1935 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1936 ioc_srch->name, ioc_srch->alt_ioc->name);
1939 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1940 ioc->name, ioc_srch->name));
1941 ioc_srch->alt_ioc = ioc;
1942 ioc->alt_ioc = ioc_srch;
1948 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1950 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1951 * @this: Pointer to MPT adapter structure
1954 mpt_adapter_disable(MPT_ADAPTER *ioc)
1959 if (ioc->cached_fw != NULL) {
1960 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1961 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1962 printk(KERN_WARNING MYNAM
1963 ": firmware downloadboot failure (%d)!\n", ret);
1967 /* Disable adapter interrupts! */
1968 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1970 /* Clear any lingering interrupt */
1971 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1973 if (ioc->alloc != NULL) {
1975 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1976 ioc->name, ioc->alloc, ioc->alloc_sz));
1977 pci_free_consistent(ioc->pcidev, sz,
1978 ioc->alloc, ioc->alloc_dma);
1979 ioc->reply_frames = NULL;
1980 ioc->req_frames = NULL;
1982 ioc->alloc_total -= sz;
1985 if (ioc->sense_buf_pool != NULL) {
1986 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1987 pci_free_consistent(ioc->pcidev, sz,
1988 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1989 ioc->sense_buf_pool = NULL;
1990 ioc->alloc_total -= sz;
1993 if (ioc->events != NULL){
1994 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1997 ioc->alloc_total -= sz;
2000 if (ioc->cached_fw != NULL) {
2001 sz = ioc->facts.FWImageSize;
2002 pci_free_consistent(ioc->pcidev, sz,
2003 ioc->cached_fw, ioc->cached_fw_dma);
2004 ioc->cached_fw = NULL;
2005 ioc->alloc_total -= sz;
2008 kfree(ioc->spi_data.nvram);
2009 kfree(ioc->raid_data.pIocPg3);
2010 ioc->spi_data.nvram = NULL;
2011 ioc->raid_data.pIocPg3 = NULL;
2013 if (ioc->spi_data.pIocPg4 != NULL) {
2014 sz = ioc->spi_data.IocPg4Sz;
2015 pci_free_consistent(ioc->pcidev, sz,
2016 ioc->spi_data.pIocPg4,
2017 ioc->spi_data.IocPg4_dma);
2018 ioc->spi_data.pIocPg4 = NULL;
2019 ioc->alloc_total -= sz;
2022 if (ioc->ReqToChain != NULL) {
2023 kfree(ioc->ReqToChain);
2024 kfree(ioc->RequestNB);
2025 ioc->ReqToChain = NULL;
2028 kfree(ioc->ChainToChain);
2029 ioc->ChainToChain = NULL;
2031 if (ioc->HostPageBuffer != NULL) {
2032 if((ret = mpt_host_page_access_control(ioc,
2033 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2034 printk(KERN_ERR MYNAM
2035 ": %s: host page buffers free failed (%d)!\n",
2038 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2039 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2040 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2041 ioc->HostPageBuffer,
2042 ioc->HostPageBuffer_dma);
2043 ioc->HostPageBuffer = NULL;
2044 ioc->HostPageBuffer_sz = 0;
2045 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2049 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2051 * mpt_adapter_dispose - Free all resources associated with a MPT
2053 * @ioc: Pointer to MPT adapter structure
2055 * This routine unregisters h/w resources and frees all alloc'd memory
2056 * associated with a MPT adapter structure.
2059 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2061 int sz_first, sz_last;
2066 sz_first = ioc->alloc_total;
2068 mpt_adapter_disable(ioc);
2070 if (ioc->pci_irq != -1) {
2071 free_irq(ioc->pci_irq, ioc);
2075 if (ioc->memmap != NULL) {
2076 iounmap(ioc->memmap);
2080 #if defined(CONFIG_MTRR) && 0
2081 if (ioc->mtrr_reg > 0) {
2082 mtrr_del(ioc->mtrr_reg, 0, 0);
2083 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2087 /* Zap the adapter lookup ptr! */
2088 list_del(&ioc->list);
2090 sz_last = ioc->alloc_total;
2091 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2092 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2098 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2099 * @ioc: Pointer to MPT adapter structure
2102 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2106 printk(KERN_INFO "%s: ", ioc->name);
2107 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2108 printk("%s: ", ioc->prod_name+3);
2109 printk("Capabilities={");
2111 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2112 printk("Initiator");
2116 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2117 printk("%sTarget", i ? "," : "");
2121 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2122 printk("%sLAN", i ? "," : "");
2128 * This would probably evoke more questions than it's worth
2130 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2131 printk("%sLogBusAddr", i ? "," : "");
2139 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2141 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2142 * @ioc: Pointer to MPT_ADAPTER structure
2143 * @force: Force hard KickStart of IOC
2144 * @sleepFlag: Specifies whether the process can sleep
2147 * 1 - DIAG reset and READY
2148 * 0 - READY initially OR soft reset and READY
2149 * -1 - Any failure on KickStart
2150 * -2 - Msg Unit Reset Failed
2151 * -3 - IO Unit Reset Failed
2152 * -4 - IOC owned by a PEER
2155 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2160 int hard_reset_done = 0;
2165 /* Get current [raw] IOC state */
2166 ioc_state = mpt_GetIocState(ioc, 0);
2167 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2170 * Check to see if IOC got left/stuck in doorbell handshake
2171 * grip of death. If so, hard reset the IOC.
2173 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2175 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2179 /* Is it already READY? */
2180 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2184 * Check to see if IOC is in FAULT state.
2186 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2188 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2190 printk(KERN_WARNING " FAULT code = %04xh\n",
2191 ioc_state & MPI_DOORBELL_DATA_MASK);
2195 * Hmmm... Did it get left operational?
2197 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2198 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2202 * If PCI Peer, exit.
2203 * Else, if no fault conditions are present, issue a MessageUnitReset
2204 * Else, fall through to KickStart case
2206 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2207 dinitprintk((KERN_INFO MYNAM
2208 ": whoinit 0x%x statefault %d force %d\n",
2209 whoinit, statefault, force));
2210 if (whoinit == MPI_WHOINIT_PCI_PEER)
2213 if ((statefault == 0 ) && (force == 0)) {
2214 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2221 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2222 if (hard_reset_done < 0)
2226 * Loop here waiting for IOC to come READY.
2229 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2231 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2232 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2234 * BIOS or previous driver load left IOC in OP state.
2235 * Reset messaging FIFOs.
2237 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2238 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2241 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2243 * Something is wrong. Try to get IOC back
2246 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2247 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2254 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2255 ioc->name, (int)((ii+5)/HZ));
2259 if (sleepFlag == CAN_SLEEP) {
2260 msleep_interruptible(1);
2262 mdelay (1); /* 1 msec delay */
2267 if (statefault < 3) {
2268 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2270 statefault==1 ? "stuck handshake" : "IOC FAULT");
2273 return hard_reset_done;
2276 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2278 * mpt_GetIocState - Get the current state of a MPT adapter.
2279 * @ioc: Pointer to MPT_ADAPTER structure
2280 * @cooked: Request raw or cooked IOC state
2282 * Returns all IOC Doorbell register bits if cooked==0, else just the
2283 * Doorbell bits in MPI_IOC_STATE_MASK.
2286 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2291 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2292 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2293 sc = s & MPI_IOC_STATE_MASK;
2296 ioc->last_state = sc;
2298 return cooked ? sc : s;
2301 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2303 * GetIocFacts - Send IOCFacts request to MPT adapter.
2304 * @ioc: Pointer to MPT_ADAPTER structure
2305 * @sleepFlag: Specifies whether the process can sleep
2306 * @reason: If recovery, only update facts.
2308 * Returns 0 for success, non-zero for failure.
2311 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2313 IOCFacts_t get_facts;
2314 IOCFactsReply_t *facts;
2322 /* IOC *must* NOT be in RESET state! */
2323 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2324 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2330 facts = &ioc->facts;
2332 /* Destination (reply area)... */
2333 reply_sz = sizeof(*facts);
2334 memset(facts, 0, reply_sz);
2336 /* Request area (get_facts on the stack right now!) */
2337 req_sz = sizeof(get_facts);
2338 memset(&get_facts, 0, req_sz);
2340 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2341 /* Assert: All other get_facts fields are zero! */
2343 dinitprintk((MYIOC_s_INFO_FMT
2344 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2345 ioc->name, req_sz, reply_sz));
2347 /* No non-zero fields in the get_facts request are greater than
2348 * 1 byte in size, so we can just fire it off as is.
2350 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2351 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2356 * Now byte swap (GRRR) the necessary fields before any further
2357 * inspection of reply contents.
2359 * But need to do some sanity checks on MsgLength (byte) field
2360 * to make sure we don't zero IOC's req_sz!
2362 /* Did we get a valid reply? */
2363 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2364 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2366 * If not been here, done that, save off first WhoInit value
2368 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2369 ioc->FirstWhoInit = facts->WhoInit;
2372 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2373 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2374 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2375 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2376 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2377 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2378 /* CHECKME! IOCStatus, IOCLogInfo */
2380 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2381 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2384 * FC f/w version changed between 1.1 and 1.2
2385 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2386 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2388 if (facts->MsgVersion < 0x0102) {
2390 * Handle old FC f/w style, convert to new...
2392 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2393 facts->FWVersion.Word =
2394 ((oldv<<12) & 0xFF000000) |
2395 ((oldv<<8) & 0x000FFF00);
2397 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2399 facts->ProductID = le16_to_cpu(facts->ProductID);
2400 facts->CurrentHostMfaHighAddr =
2401 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2402 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2403 facts->CurrentSenseBufferHighAddr =
2404 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2405 facts->CurReplyFrameSize =
2406 le16_to_cpu(facts->CurReplyFrameSize);
2407 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2410 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2411 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2412 * to 14 in MPI-1.01.0x.
2414 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2415 facts->MsgVersion > 0x0100) {
2416 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2419 sz = facts->FWImageSize;
2424 facts->FWImageSize = sz;
2426 if (!facts->RequestFrameSize) {
2427 /* Something is wrong! */
2428 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2433 r = sz = facts->BlockSize;
2434 vv = ((63 / (sz * 4)) + 1) & 0x03;
2435 ioc->NB_for_64_byte_frame = vv;
2441 ioc->NBShiftFactor = shiftFactor;
2442 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2443 ioc->name, vv, shiftFactor, r));
2445 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2447 * Set values for this IOC's request & reply frame sizes,
2448 * and request & reply queue depths...
2450 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2451 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2452 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2453 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2455 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2456 ioc->name, ioc->reply_sz, ioc->reply_depth));
2457 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2458 ioc->name, ioc->req_sz, ioc->req_depth));
2460 /* Get port facts! */
2461 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2465 printk(MYIOC_s_ERR_FMT
2466 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2467 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2468 RequestFrameSize)/sizeof(u32)));
2475 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2477 * GetPortFacts - Send PortFacts request to MPT adapter.
2478 * @ioc: Pointer to MPT_ADAPTER structure
2479 * @portnum: Port number
2480 * @sleepFlag: Specifies whether the process can sleep
2482 * Returns 0 for success, non-zero for failure.
2485 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2487 PortFacts_t get_pfacts;
2488 PortFactsReply_t *pfacts;
2493 /* IOC *must* NOT be in RESET state! */
2494 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2495 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2501 pfacts = &ioc->pfacts[portnum];
2503 /* Destination (reply area)... */
2504 reply_sz = sizeof(*pfacts);
2505 memset(pfacts, 0, reply_sz);
2507 /* Request area (get_pfacts on the stack right now!) */
2508 req_sz = sizeof(get_pfacts);
2509 memset(&get_pfacts, 0, req_sz);
2511 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2512 get_pfacts.PortNumber = portnum;
2513 /* Assert: All other get_pfacts fields are zero! */
2515 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2516 ioc->name, portnum));
2518 /* No non-zero fields in the get_pfacts request are greater than
2519 * 1 byte in size, so we can just fire it off as is.
2521 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2522 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2526 /* Did we get a valid reply? */
2528 /* Now byte swap the necessary fields in the response. */
2529 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2530 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2531 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2532 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2533 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2534 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2535 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2536 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2537 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2542 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2544 * SendIocInit - Send IOCInit request to MPT adapter.
2545 * @ioc: Pointer to MPT_ADAPTER structure
2546 * @sleepFlag: Specifies whether the process can sleep
2548 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2550 * Returns 0 for success, non-zero for failure.
2553 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2556 MPIDefaultReply_t init_reply;
2562 memset(&ioc_init, 0, sizeof(ioc_init));
2563 memset(&init_reply, 0, sizeof(init_reply));
2565 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2566 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2568 /* If we are in a recovery mode and we uploaded the FW image,
2569 * then this pointer is not NULL. Skip the upload a second time.
2570 * Set this flag if cached_fw set for either IOC.
2572 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2576 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2577 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2579 if(ioc->bus_type == SAS)
2580 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2581 else if(ioc->bus_type == FC)
2582 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2584 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2585 ioc_init.MaxBuses = MPT_MAX_BUS;
2586 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2587 ioc->name, ioc->facts.MsgVersion));
2588 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2589 // set MsgVersion and HeaderVersion host driver was built with
2590 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2591 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2593 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2594 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2595 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2598 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2600 if (sizeof(dma_addr_t) == sizeof(u64)) {
2601 /* Save the upper 32-bits of the request
2602 * (reply) and sense buffers.
2604 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2605 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2607 /* Force 32-bit addressing */
2608 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2609 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2612 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2613 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2614 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2615 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2617 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2618 ioc->name, &ioc_init));
2620 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2621 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2623 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2627 /* No need to byte swap the multibyte fields in the reply
2628 * since we don't even look at it's contents.
2631 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2632 ioc->name, &ioc_init));
2634 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2635 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2639 /* YIKES! SUPER IMPORTANT!!!
2640 * Poll IocState until _OPERATIONAL while IOC is doing
2641 * LoopInit and TargetDiscovery!
2644 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2645 state = mpt_GetIocState(ioc, 1);
2646 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2647 if (sleepFlag == CAN_SLEEP) {
2648 msleep_interruptible(1);
2654 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2655 ioc->name, (int)((count+5)/HZ));
2659 state = mpt_GetIocState(ioc, 1);
2662 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2670 * SendPortEnable - Send PortEnable request to MPT adapter port.
2671 * @ioc: Pointer to MPT_ADAPTER structure
2672 * @portnum: Port number to enable
2673 * @sleepFlag: Specifies whether the process can sleep
2675 * Send PortEnable to bring IOC to OPERATIONAL state.
2677 * Returns 0 for success, non-zero for failure.
2680 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2682 PortEnable_t port_enable;
2683 MPIDefaultReply_t reply_buf;
2688 /* Destination... */
2689 reply_sz = sizeof(MPIDefaultReply_t);
2690 memset(&reply_buf, 0, reply_sz);
2692 req_sz = sizeof(PortEnable_t);
2693 memset(&port_enable, 0, req_sz);
2695 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2696 port_enable.PortNumber = portnum;
2697 /* port_enable.ChainOffset = 0; */
2698 /* port_enable.MsgFlags = 0; */
2699 /* port_enable.MsgContext = 0; */
2701 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2702 ioc->name, portnum, &port_enable));
2704 /* RAID FW may take a long time to enable
2706 if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2707 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
2708 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2709 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2711 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2712 reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
2718 * ioc: Pointer to MPT_ADAPTER structure
2719 * size - total FW bytes
2722 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2725 return; /* use already allocated memory */
2726 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2727 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2728 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2730 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2731 ioc->alloc_total += size;
2735 * If alt_img is NULL, delete from ioc structure.
2736 * Else, delete a secondary image in same format.
2739 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2743 sz = ioc->facts.FWImageSize;
2744 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2745 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2746 pci_free_consistent(ioc->pcidev, sz,
2747 ioc->cached_fw, ioc->cached_fw_dma);
2748 ioc->cached_fw = NULL;
2754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2756 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2757 * @ioc: Pointer to MPT_ADAPTER structure
2758 * @sleepFlag: Specifies whether the process can sleep
2760 * Returns 0 for success, >0 for handshake failure
2761 * <0 for fw upload failure.
2763 * Remark: If bound IOC and a successful FWUpload was performed
2764 * on the bound IOC, the second image is discarded
2765 * and memory is free'd. Both channels must upload to prevent
2766 * IOC from running in degraded mode.
2769 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2771 u8 request[ioc->req_sz];
2772 u8 reply[sizeof(FWUploadReply_t)];
2773 FWUpload_t *prequest;
2774 FWUploadReply_t *preply;
2775 FWUploadTCSGE_t *ptcsge;
2778 int ii, sz, reply_sz;
2781 /* If the image size is 0, we are done.
2783 if ((sz = ioc->facts.FWImageSize) == 0)
2786 mpt_alloc_fw_memory(ioc, sz);
2788 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2789 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2791 if (ioc->cached_fw == NULL) {
2797 prequest = (FWUpload_t *)&request;
2798 preply = (FWUploadReply_t *)&reply;
2800 /* Destination... */
2801 memset(prequest, 0, ioc->req_sz);
2803 reply_sz = sizeof(reply);
2804 memset(preply, 0, reply_sz);
2806 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2807 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2809 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2810 ptcsge->DetailsLength = 12;
2811 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2812 ptcsge->ImageSize = cpu_to_le32(sz);
2814 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2816 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2817 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2819 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2820 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2821 prequest, sgeoffset));
2822 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2824 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2825 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2827 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2829 cmdStatus = -EFAULT;
2831 /* Handshake transfer was complete and successful.
2832 * Check the Reply Frame.
2834 int status, transfer_sz;
2835 status = le16_to_cpu(preply->IOCStatus);
2836 if (status == MPI_IOCSTATUS_SUCCESS) {
2837 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2838 if (transfer_sz == sz)
2842 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2843 ioc->name, cmdStatus));
2848 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2850 mpt_free_fw_memory(ioc);
2856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2858 * mpt_downloadboot - DownloadBoot code
2859 * @ioc: Pointer to MPT_ADAPTER structure
2860 * @flag: Specify which part of IOC memory is to be uploaded.
2861 * @sleepFlag: Specifies whether the process can sleep
2863 * FwDownloadBoot requires Programmed IO access.
2865 * Returns 0 for success
2866 * -1 FW Image size is 0
2867 * -2 No valid cached_fw Pointer
2868 * <0 for fw upload failure.
2871 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2873 MpiExtImageHeader_t *pExtImage;
2883 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2884 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2886 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2887 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2888 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2889 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2890 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2891 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2893 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2896 if (sleepFlag == CAN_SLEEP) {
2897 msleep_interruptible(1);
2902 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2903 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2905 for (count = 0; count < 30; count ++) {
2906 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2907 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2908 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2913 if (sleepFlag == CAN_SLEEP) {
2914 msleep_interruptible (100);
2920 if ( count == 30 ) {
2921 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2922 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2923 ioc->name, diag0val));
2927 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2928 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2929 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2930 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2931 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2932 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2934 /* Set the DiagRwEn and Disable ARM bits */
2935 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2937 fwSize = (pFwHeader->ImageSize + 3)/4;
2938 ptrFw = (u32 *) pFwHeader;
2940 /* Write the LoadStartAddress to the DiagRw Address Register
2941 * using Programmed IO
2943 if (ioc->errata_flag_1064)
2944 pci_enable_io_access(ioc->pcidev);
2946 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2947 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2948 ioc->name, pFwHeader->LoadStartAddress));
2950 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2951 ioc->name, fwSize*4, ptrFw));
2953 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2956 nextImage = pFwHeader->NextImageHeaderOffset;
2958 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2960 load_addr = pExtImage->LoadStartAddress;
2962 fwSize = (pExtImage->ImageSize + 3) >> 2;
2963 ptrFw = (u32 *)pExtImage;
2965 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
2966 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
2967 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2970 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2972 nextImage = pExtImage->NextImageHeaderOffset;
2975 /* Write the IopResetVectorRegAddr */
2976 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2977 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2979 /* Write the IopResetVectorValue */
2980 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2981 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2983 /* Clear the internal flash bad bit - autoincrementing register,
2984 * so must do two writes.
2986 if (ioc->bus_type == SCSI) {
2988 * 1030 and 1035 H/W errata, workaround to access
2989 * the ClearFlashBadSignatureBit
2991 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2992 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2993 diagRwData |= 0x40000000;
2994 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2995 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2997 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
2998 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2999 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3000 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3003 if (sleepFlag == CAN_SLEEP) {
3004 msleep_interruptible (1);
3010 if (ioc->errata_flag_1064)
3011 pci_disable_io_access(ioc->pcidev);
3013 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3014 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3015 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3016 ioc->name, diag0val));
3017 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3018 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3019 ioc->name, diag0val));
3020 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3022 /* Write 0xFF to reset the sequencer */
3023 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3025 if (ioc->bus_type == SAS) {
3026 ioc_state = mpt_GetIocState(ioc, 0);
3027 if ( (GetIocFacts(ioc, sleepFlag,
3028 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3029 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3030 ioc->name, ioc_state));
3035 for (count=0; count<HZ*20; count++) {
3036 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3037 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3038 ioc->name, count, ioc_state));
3039 if (ioc->bus_type == SAS) {
3042 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3043 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3047 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3051 if (sleepFlag == CAN_SLEEP) {
3052 msleep_interruptible (10);
3057 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3058 ioc->name, ioc_state));
3062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3064 * KickStart - Perform hard reset of MPT adapter.
3065 * @ioc: Pointer to MPT_ADAPTER structure
3066 * @force: Force hard reset
3067 * @sleepFlag: Specifies whether the process can sleep
3069 * This routine places MPT adapter in diagnostic mode via the
3070 * WriteSequence register, and then performs a hard reset of adapter
3071 * via the Diagnostic register.
3073 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3074 * or NO_SLEEP (interrupt thread, use mdelay)
3075 * force - 1 if doorbell active, board fault state
3076 * board operational, IOC_RECOVERY or
3077 * IOC_BRINGUP and there is an alt_ioc.
3081 * 1 - hard reset, READY
3082 * 0 - no reset due to History bit, READY
3083 * -1 - no reset due to History bit but not READY
3084 * OR reset but failed to come READY
3085 * -2 - no reset, could not enter DIAG mode
3086 * -3 - reset but bad FW bit
3089 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3091 int hard_reset_done = 0;
3095 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3096 if (ioc->bus_type == SCSI) {
3097 /* Always issue a Msg Unit Reset first. This will clear some
3098 * SCSI bus hang conditions.
3100 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3102 if (sleepFlag == CAN_SLEEP) {
3103 msleep_interruptible (1000);
3109 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3110 if (hard_reset_done < 0)
3111 return hard_reset_done;
3113 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3116 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3117 for (cnt=0; cnt<cntdn; cnt++) {
3118 ioc_state = mpt_GetIocState(ioc, 1);
3119 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3120 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3122 return hard_reset_done;
3124 if (sleepFlag == CAN_SLEEP) {
3125 msleep_interruptible (10);
3131 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3132 ioc->name, ioc_state);
3136 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3138 * mpt_diag_reset - Perform hard reset of the adapter.
3139 * @ioc: Pointer to MPT_ADAPTER structure
3140 * @ignore: Set if to honor and clear to ignore
3141 * the reset history bit
3142 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3143 * else set to NO_SLEEP (use mdelay instead)
3145 * This routine places the adapter in diagnostic mode via the
3146 * WriteSequence register and then performs a hard reset of adapter
3147 * via the Diagnostic register. Adapter should be in ready state
3148 * upon successful completion.
3150 * Returns: 1 hard reset successful
3151 * 0 no reset performed because reset history bit set
3152 * -2 enabling diagnostic mode failed
3153 * -3 diagnostic reset failed
3156 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3160 int hard_reset_done = 0;
3166 /* Clear any existing interrupts */
3167 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3169 /* Use "Diagnostic reset" method! (only thing available!) */
3170 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3174 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3175 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3176 ioc->name, diag0val, diag1val));
3179 /* Do the reset if we are told to ignore the reset history
3180 * or if the reset history is 0
3182 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3183 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3184 /* Write magic sequence to WriteSequence register
3185 * Loop until in diagnostic mode
3187 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3188 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3189 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3190 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3191 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3192 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3195 if (sleepFlag == CAN_SLEEP) {
3196 msleep_interruptible (100);
3203 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3204 ioc->name, diag0val);
3209 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3211 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3212 ioc->name, diag0val));
3217 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3218 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3219 ioc->name, diag0val, diag1val));
3222 * Disable the ARM (Bug fix)
3225 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3229 * Now hit the reset bit in the Diagnostic register
3230 * (THE BIG HAMMER!) (Clears DRWE bit).
3232 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3233 hard_reset_done = 1;
3234 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3238 * Call each currently registered protocol IOC reset handler
3239 * with pre-reset indication.
3240 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3241 * MptResetHandlers[] registered yet.
3247 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3248 if (MptResetHandlers[ii]) {
3249 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3251 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3253 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3254 ioc->name, ioc->alt_ioc->name, ii));
3255 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3259 /* FIXME? Examine results here? */
3262 if (ioc->cached_fw) {
3263 /* If the DownloadBoot operation fails, the
3264 * IOC will be left unusable. This is a fatal error
3265 * case. _diag_reset will return < 0
3267 for (count = 0; count < 30; count ++) {
3268 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3269 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3274 if (sleepFlag == CAN_SLEEP) {
3275 msleep_interruptible (1000);
3280 if ((count = mpt_downloadboot(ioc,
3281 (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
3282 printk(KERN_WARNING MYNAM
3283 ": firmware downloadboot failure (%d)!\n", count);
3287 /* Wait for FW to reload and for board
3288 * to go to the READY state.
3289 * Maximum wait is 60 seconds.
3290 * If fail, no error will check again
3291 * with calling program.
3293 for (count = 0; count < 60; count ++) {
3294 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3295 doorbell &= MPI_IOC_STATE_MASK;
3297 if (doorbell == MPI_IOC_STATE_READY) {
3302 if (sleepFlag == CAN_SLEEP) {
3303 msleep_interruptible (1000);
3311 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3314 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3315 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3316 ioc->name, diag0val, diag1val));
3319 /* Clear RESET_HISTORY bit! Place board in the
3320 * diagnostic mode to update the diag register.
3322 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3324 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3325 /* Write magic sequence to WriteSequence register
3326 * Loop until in diagnostic mode
3328 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3329 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3330 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3331 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3332 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3333 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3336 if (sleepFlag == CAN_SLEEP) {
3337 msleep_interruptible (100);
3344 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3345 ioc->name, diag0val);
3348 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3350 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3351 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3352 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3353 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3354 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3358 /* Disable Diagnostic Mode
3360 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3362 /* Check FW reload status flags.
3364 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3365 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3366 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3367 ioc->name, diag0val);
3373 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3374 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3375 ioc->name, diag0val, diag1val));
3379 * Reset flag that says we've enabled event notification
3381 ioc->facts.EventState = 0;
3384 ioc->alt_ioc->facts.EventState = 0;
3386 return hard_reset_done;
3389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3391 * SendIocReset - Send IOCReset request to MPT adapter.
3392 * @ioc: Pointer to MPT_ADAPTER structure
3393 * @reset_type: reset type, expected values are
3394 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3396 * Send IOCReset request to the MPT adapter.
3398 * Returns 0 for success, non-zero for failure.
3401 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3407 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3408 ioc->name, reset_type));
3409 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3410 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3413 /* FW ACK'd request, wait for READY state
3416 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3418 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3422 if (sleepFlag != CAN_SLEEP)
3425 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3426 ioc->name, (int)((count+5)/HZ));
3430 if (sleepFlag == CAN_SLEEP) {
3431 msleep_interruptible(1);
3433 mdelay (1); /* 1 msec delay */
3438 * Cleanup all event stuff for this IOC; re-issue EventNotification
3439 * request if needed.
3441 if (ioc->facts.Function)
3442 ioc->facts.EventState = 0;
3447 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3449 * initChainBuffers - Allocate memory for and initialize
3450 * chain buffers, chain buffer control arrays and spinlock.
3451 * @hd: Pointer to MPT_SCSI_HOST structure
3452 * @init: If set, initialize the spin lock.
3455 initChainBuffers(MPT_ADAPTER *ioc)
3458 int sz, ii, num_chain;
3459 int scale, num_sge, numSGE;
3461 /* ReqToChain size must equal the req_depth
3464 if (ioc->ReqToChain == NULL) {
3465 sz = ioc->req_depth * sizeof(int);
3466 mem = kmalloc(sz, GFP_ATOMIC);
3470 ioc->ReqToChain = (int *) mem;
3471 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3472 ioc->name, mem, sz));
3473 mem = kmalloc(sz, GFP_ATOMIC);
3477 ioc->RequestNB = (int *) mem;
3478 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3479 ioc->name, mem, sz));
3481 for (ii = 0; ii < ioc->req_depth; ii++) {
3482 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3485 /* ChainToChain size must equal the total number
3486 * of chain buffers to be allocated.
3489 * Calculate the number of chain buffers needed(plus 1) per I/O
3490 * then multiply the the maximum number of simultaneous cmds
3492 * num_sge = num sge in request frame + last chain buffer
3493 * scale = num sge per chain buffer if no chain element
3495 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3496 if (sizeof(dma_addr_t) == sizeof(u64))
3497 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3499 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3501 if (sizeof(dma_addr_t) == sizeof(u64)) {
3502 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3503 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3505 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3506 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3508 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3509 ioc->name, num_sge, numSGE));
3511 if ( numSGE > MPT_SCSI_SG_DEPTH )
3512 numSGE = MPT_SCSI_SG_DEPTH;
3515 while (numSGE - num_sge > 0) {
3517 num_sge += (scale - 1);
3521 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3522 ioc->name, numSGE, num_sge, num_chain));
3524 if (ioc->bus_type == SCSI)
3525 num_chain *= MPT_SCSI_CAN_QUEUE;
3527 num_chain *= MPT_FC_CAN_QUEUE;
3529 ioc->num_chain = num_chain;
3531 sz = num_chain * sizeof(int);
3532 if (ioc->ChainToChain == NULL) {
3533 mem = kmalloc(sz, GFP_ATOMIC);
3537 ioc->ChainToChain = (int *) mem;
3538 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3539 ioc->name, mem, sz));
3541 mem = (u8 *) ioc->ChainToChain;
3543 memset(mem, 0xFF, sz);
3547 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3549 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3550 * @ioc: Pointer to MPT_ADAPTER structure
3552 * This routine allocates memory for the MPT reply and request frame
3553 * pools (if necessary), and primes the IOC reply FIFO with
3556 * Returns 0 for success, non-zero for failure.
3559 PrimeIocFifos(MPT_ADAPTER *ioc)
3562 unsigned long flags;
3563 dma_addr_t alloc_dma;
3565 int i, reply_sz, sz, total_size, num_chain;
3567 /* Prime reply FIFO... */
3569 if (ioc->reply_frames == NULL) {
3570 if ( (num_chain = initChainBuffers(ioc)) < 0)
3573 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3574 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3575 ioc->name, ioc->reply_sz, ioc->reply_depth));
3576 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3577 ioc->name, reply_sz, reply_sz));
3579 sz = (ioc->req_sz * ioc->req_depth);
3580 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3581 ioc->name, ioc->req_sz, ioc->req_depth));
3582 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3583 ioc->name, sz, sz));
3586 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3587 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3588 ioc->name, ioc->req_sz, num_chain));
3589 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3590 ioc->name, sz, sz, num_chain));
3593 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3595 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3600 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3601 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3603 memset(mem, 0, total_size);
3604 ioc->alloc_total += total_size;
3606 ioc->alloc_dma = alloc_dma;
3607 ioc->alloc_sz = total_size;
3608 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3609 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3611 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3612 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3614 alloc_dma += reply_sz;
3617 /* Request FIFO - WE manage this! */
3619 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3620 ioc->req_frames_dma = alloc_dma;
3622 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3623 ioc->name, mem, (void *)(ulong)alloc_dma));
3625 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3627 #if defined(CONFIG_MTRR) && 0
3629 * Enable Write Combining MTRR for IOC's memory region.
3630 * (at least as much as we can; "size and base must be
3631 * multiples of 4 kiB"
3633 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3635 MTRR_TYPE_WRCOMB, 1);
3636 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3637 ioc->name, ioc->req_frames_dma, sz));
3640 for (i = 0; i < ioc->req_depth; i++) {
3641 alloc_dma += ioc->req_sz;
3645 ioc->ChainBuffer = mem;
3646 ioc->ChainBufferDMA = alloc_dma;
3648 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3649 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3651 /* Initialize the free chain Q.
3654 INIT_LIST_HEAD(&ioc->FreeChainQ);
3656 /* Post the chain buffers to the FreeChainQ.
3658 mem = (u8 *)ioc->ChainBuffer;
3659 for (i=0; i < num_chain; i++) {
3660 mf = (MPT_FRAME_HDR *) mem;
3661 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3665 /* Initialize Request frames linked list
3667 alloc_dma = ioc->req_frames_dma;
3668 mem = (u8 *) ioc->req_frames;
3670 spin_lock_irqsave(&ioc->FreeQlock, flags);
3671 INIT_LIST_HEAD(&ioc->FreeQ);
3672 for (i = 0; i < ioc->req_depth; i++) {
3673 mf = (MPT_FRAME_HDR *) mem;
3675 /* Queue REQUESTs *internally*! */
3676 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3680 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3682 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3683 ioc->sense_buf_pool =
3684 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3685 if (ioc->sense_buf_pool == NULL) {
3686 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3691 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3692 ioc->alloc_total += sz;
3693 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3694 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3698 /* Post Reply frames to FIFO
3700 alloc_dma = ioc->alloc_dma;
3701 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3702 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3704 for (i = 0; i < ioc->reply_depth; i++) {
3705 /* Write each address to the IOC! */
3706 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3707 alloc_dma += ioc->reply_sz;
3713 if (ioc->alloc != NULL) {
3715 pci_free_consistent(ioc->pcidev,
3717 ioc->alloc, ioc->alloc_dma);
3718 ioc->reply_frames = NULL;
3719 ioc->req_frames = NULL;
3720 ioc->alloc_total -= sz;
3722 if (ioc->sense_buf_pool != NULL) {
3723 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3724 pci_free_consistent(ioc->pcidev,
3726 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3727 ioc->sense_buf_pool = NULL;
3732 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3734 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3735 * from IOC via doorbell handshake method.
3736 * @ioc: Pointer to MPT_ADAPTER structure
3737 * @reqBytes: Size of the request in bytes
3738 * @req: Pointer to MPT request frame
3739 * @replyBytes: Expected size of the reply in bytes
3740 * @u16reply: Pointer to area where reply should be written
3741 * @maxwait: Max wait time for a reply (in seconds)
3742 * @sleepFlag: Specifies whether the process can sleep
3744 * NOTES: It is the callers responsibility to byte-swap fields in the
3745 * request which are greater than 1 byte in size. It is also the
3746 * callers responsibility to byte-swap response fields which are
3747 * greater than 1 byte in size.
3749 * Returns 0 for success, non-zero for failure.
3752 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3753 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3755 MPIDefaultReply_t *mptReply;
3760 * Get ready to cache a handshake reply
3762 ioc->hs_reply_idx = 0;
3763 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3764 mptReply->MsgLength = 0;
3767 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3768 * then tell IOC that we want to handshake a request of N words.
3769 * (WRITE u32val to Doorbell reg).
3771 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3772 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3773 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3774 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3777 * Wait for IOC's doorbell handshake int
3779 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3782 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3783 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3785 /* Read doorbell and check for active bit */
3786 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3790 * Clear doorbell int (WRITE 0 to IntStatus reg),
3791 * then wait for IOC to ACKnowledge that it's ready for
3792 * our handshake request.
3794 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3795 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3800 u8 *req_as_bytes = (u8 *) req;
3803 * Stuff request words via doorbell handshake,
3804 * with ACK from IOC for each.
3806 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3807 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3808 (req_as_bytes[(ii*4) + 1] << 8) |
3809 (req_as_bytes[(ii*4) + 2] << 16) |
3810 (req_as_bytes[(ii*4) + 3] << 24));
3812 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3813 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3817 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3818 DBG_DUMP_REQUEST_FRAME_HDR(req)
3820 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3821 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3824 * Wait for completion of doorbell handshake reply from the IOC
3826 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3829 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3830 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3833 * Copy out the cached reply...
3835 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3836 u16reply[ii] = ioc->hs_reply[ii];
3844 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3846 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3847 * in it's IntStatus register.
3848 * @ioc: Pointer to MPT_ADAPTER structure
3849 * @howlong: How long to wait (in seconds)
3850 * @sleepFlag: Specifies whether the process can sleep
3852 * This routine waits (up to ~2 seconds max) for IOC doorbell
3853 * handshake ACKnowledge.
3855 * Returns a negative value on failure, else wait loop count.
3858 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3864 cntdn = 1000 * howlong;
3866 if (sleepFlag == CAN_SLEEP) {
3868 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3869 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3871 msleep_interruptible (1);
3876 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3877 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3885 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3890 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3891 ioc->name, count, intstat);
3895 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3897 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3898 * in it's IntStatus register.
3899 * @ioc: Pointer to MPT_ADAPTER structure
3900 * @howlong: How long to wait (in seconds)
3901 * @sleepFlag: Specifies whether the process can sleep
3903 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3905 * Returns a negative value on failure, else wait loop count.
3908 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3914 cntdn = 1000 * howlong;
3915 if (sleepFlag == CAN_SLEEP) {
3917 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3918 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3920 msleep_interruptible(1);
3925 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3926 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3934 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3935 ioc->name, count, howlong));
3939 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3940 ioc->name, count, intstat);
3944 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3946 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3947 * @ioc: Pointer to MPT_ADAPTER structure
3948 * @howlong: How long to wait (in seconds)
3949 * @sleepFlag: Specifies whether the process can sleep
3951 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3952 * Reply is cached to IOC private area large enough to hold a maximum
3953 * of 128 bytes of reply data.
3955 * Returns a negative value on failure, else size of reply in WORDS.
3958 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3963 u16 *hs_reply = ioc->hs_reply;
3964 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3967 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3970 * Get first two u16's so we can look at IOC's intended reply MsgLength
3973 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3976 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3977 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3978 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3981 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3982 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3986 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3987 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3988 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3991 * If no error (and IOC said MsgLength is > 0), piece together
3992 * reply 16 bits at a time.
3994 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3995 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3997 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3998 /* don't overflow our IOC hs_reply[] buffer! */
3999 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4000 hs_reply[u16cnt] = hword;
4001 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4004 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4006 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4009 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4014 else if (u16cnt != (2 * mptReply->MsgLength)) {
4017 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4022 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4023 DBG_DUMP_REPLY_FRAME(mptReply)
4025 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4026 ioc->name, t, u16cnt/2));
4030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4032 * GetLanConfigPages - Fetch LANConfig pages.
4033 * @ioc: Pointer to MPT_ADAPTER structure
4035 * Return: 0 for success
4036 * -ENOMEM if no memory available
4037 * -EPERM if not allowed due to ISR context
4038 * -EAGAIN if no msg frames currently available
4039 * -EFAULT for non-successful reply or no reply (timeout)
4042 GetLanConfigPages(MPT_ADAPTER *ioc)
4044 ConfigPageHeader_t hdr;
4046 LANPage0_t *ppage0_alloc;
4047 dma_addr_t page0_dma;
4048 LANPage1_t *ppage1_alloc;
4049 dma_addr_t page1_dma;
4054 /* Get LAN Page 0 header */
4055 hdr.PageVersion = 0;
4058 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4059 cfg.cfghdr.hdr = &hdr;
4061 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4066 if ((rc = mpt_config(ioc, &cfg)) != 0)
4069 if (hdr.PageLength > 0) {
4070 data_sz = hdr.PageLength * 4;
4071 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4074 memset((u8 *)ppage0_alloc, 0, data_sz);
4075 cfg.physAddr = page0_dma;
4076 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4078 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4080 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4081 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4085 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4088 * Normalize endianness of structure data,
4089 * by byte-swapping all > 1 byte fields!
4098 /* Get LAN Page 1 header */
4099 hdr.PageVersion = 0;
4102 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4103 cfg.cfghdr.hdr = &hdr;
4105 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4109 if ((rc = mpt_config(ioc, &cfg)) != 0)
4112 if (hdr.PageLength == 0)
4115 data_sz = hdr.PageLength * 4;
4117 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4119 memset((u8 *)ppage1_alloc, 0, data_sz);
4120 cfg.physAddr = page1_dma;
4121 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4123 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4125 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4126 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4129 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4132 * Normalize endianness of structure data,
4133 * by byte-swapping all > 1 byte fields!
4141 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4143 * GetFcPortPage0 - Fetch FCPort config Page0.
4144 * @ioc: Pointer to MPT_ADAPTER structure
4145 * @portnum: IOC Port number
4147 * Return: 0 for success
4148 * -ENOMEM if no memory available
4149 * -EPERM if not allowed due to ISR context
4150 * -EAGAIN if no msg frames currently available
4151 * -EFAULT for non-successful reply or no reply (timeout)
4154 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4156 ConfigPageHeader_t hdr;
4158 FCPortPage0_t *ppage0_alloc;
4159 FCPortPage0_t *pp0dest;
4160 dma_addr_t page0_dma;
4165 /* Get FCPort Page 0 header */
4166 hdr.PageVersion = 0;
4169 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4170 cfg.cfghdr.hdr = &hdr;
4172 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4174 cfg.pageAddr = portnum;
4177 if ((rc = mpt_config(ioc, &cfg)) != 0)
4180 if (hdr.PageLength == 0)
4183 data_sz = hdr.PageLength * 4;
4185 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4187 memset((u8 *)ppage0_alloc, 0, data_sz);
4188 cfg.physAddr = page0_dma;
4189 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4191 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4193 pp0dest = &ioc->fc_port_page0[portnum];
4194 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4195 memcpy(pp0dest, ppage0_alloc, copy_sz);
4198 * Normalize endianness of structure data,
4199 * by byte-swapping all > 1 byte fields!
4201 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4202 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4203 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4204 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4205 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4206 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4207 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4208 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4209 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4210 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4211 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4212 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4213 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4214 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4215 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4216 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4220 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4228 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4229 * @ioc: Pointer to MPT_ADAPTER structure
4230 * @sas_address: 64bit SAS Address for operation.
4231 * @target_id: specified target for operation
4232 * @bus: specified bus for operation
4233 * @persist_opcode: see below
4235 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4236 * devices not currently present.
4237 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4239 * NOTE: Don't use not this function during interrupt time.
4241 * Returns: 0 for success, non-zero error
4244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4246 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4248 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4249 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4250 MPT_FRAME_HDR *mf = NULL;
4251 MPIHeader_t *mpi_hdr;
4254 /* insure garbage is not sent to fw */
4255 switch(persist_opcode) {
4257 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4258 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4266 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4268 /* Get a MF for this command.
4270 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4271 printk("%s: no msg frames!\n",__FUNCTION__);
4275 mpi_hdr = (MPIHeader_t *) mf;
4276 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4277 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4278 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4279 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4280 sasIoUnitCntrReq->Operation = persist_opcode;
4282 init_timer(&ioc->persist_timer);
4283 ioc->persist_timer.data = (unsigned long) ioc;
4284 ioc->persist_timer.function = mpt_timer_expired;
4285 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4286 ioc->persist_wait_done=0;
4287 add_timer(&ioc->persist_timer);
4288 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4289 wait_event(mpt_waitq, ioc->persist_wait_done);
4291 sasIoUnitCntrReply =
4292 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4293 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4294 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4296 sasIoUnitCntrReply->IOCStatus,
4297 sasIoUnitCntrReply->IOCLogInfo);
4301 printk("%s: success\n",__FUNCTION__);
4305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4307 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4308 * @ioc: Pointer to MPT_ADAPTER structure
4310 * Returns: 0 for success
4311 * -ENOMEM if no memory available
4312 * -EPERM if not allowed due to ISR context
4313 * -EAGAIN if no msg frames currently available
4314 * -EFAULT for non-successful reply or no reply (timeout)
4317 GetIoUnitPage2(MPT_ADAPTER *ioc)
4319 ConfigPageHeader_t hdr;
4321 IOUnitPage2_t *ppage_alloc;
4322 dma_addr_t page_dma;
4326 /* Get the page header */
4327 hdr.PageVersion = 0;
4330 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4331 cfg.cfghdr.hdr = &hdr;
4333 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4338 if ((rc = mpt_config(ioc, &cfg)) != 0)
4341 if (hdr.PageLength == 0)
4344 /* Read the config page */
4345 data_sz = hdr.PageLength * 4;
4347 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4349 memset((u8 *)ppage_alloc, 0, data_sz);
4350 cfg.physAddr = page_dma;
4351 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4353 /* If Good, save data */
4354 if ((rc = mpt_config(ioc, &cfg)) == 0)
4355 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4357 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4363 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4364 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4365 * @ioc: Pointer to a Adapter Strucutre
4366 * @portnum: IOC port number
4368 * Return: -EFAULT if read of config page header fails
4370 * If read of SCSI Port Page 0 fails,
4371 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4372 * Adapter settings: async, narrow
4374 * If read of SCSI Port Page 2 fails,
4375 * Adapter settings valid
4376 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4381 * CHECK - what type of locking mechanisms should be used????
4384 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4389 ConfigPageHeader_t header;
4395 if (!ioc->spi_data.nvram) {
4398 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4399 mem = kmalloc(sz, GFP_ATOMIC);
4403 ioc->spi_data.nvram = (int *) mem;
4405 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4406 ioc->name, ioc->spi_data.nvram, sz));
4409 /* Invalidate NVRAM information
4411 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4412 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4415 /* Read SPP0 header, allocate memory, then read page.
4417 header.PageVersion = 0;
4418 header.PageLength = 0;
4419 header.PageNumber = 0;
4420 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4421 cfg.cfghdr.hdr = &header;
4423 cfg.pageAddr = portnum;
4424 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4426 cfg.timeout = 0; /* use default */
4427 if (mpt_config(ioc, &cfg) != 0)
4430 if (header.PageLength > 0) {
4431 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4433 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4434 cfg.physAddr = buf_dma;
4435 if (mpt_config(ioc, &cfg) != 0) {
4436 ioc->spi_data.maxBusWidth = MPT_NARROW;
4437 ioc->spi_data.maxSyncOffset = 0;
4438 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4439 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4441 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4442 ioc->name, ioc->spi_data.minSyncFactor));
4444 /* Save the Port Page 0 data
4446 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4447 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4448 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4450 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4451 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4452 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4453 ioc->name, pPP0->Capabilities));
4455 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4456 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4458 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4459 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4460 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4461 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4462 ioc->name, ioc->spi_data.minSyncFactor));
4464 ioc->spi_data.maxSyncOffset = 0;
4465 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4468 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4470 /* Update the minSyncFactor based on bus type.
4472 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4473 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4475 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4476 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4477 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4478 ioc->name, ioc->spi_data.minSyncFactor));
4483 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4488 /* SCSI Port Page 2 - Read the header then the page.
4490 header.PageVersion = 0;
4491 header.PageLength = 0;
4492 header.PageNumber = 2;
4493 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4494 cfg.cfghdr.hdr = &header;
4496 cfg.pageAddr = portnum;
4497 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4499 if (mpt_config(ioc, &cfg) != 0)
4502 if (header.PageLength > 0) {
4503 /* Allocate memory and read SCSI Port Page 2
4505 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4507 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4508 cfg.physAddr = buf_dma;
4509 if (mpt_config(ioc, &cfg) != 0) {
4510 /* Nvram data is left with INVALID mark
4514 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4515 MpiDeviceInfo_t *pdevice = NULL;
4517 /* Save the Port Page 2 data
4518 * (reformat into a 32bit quantity)
4520 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4521 ioc->spi_data.PortFlags = data;
4522 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4523 pdevice = &pPP2->DeviceSettings[ii];
4524 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4525 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4526 ioc->spi_data.nvram[ii] = data;
4530 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4534 /* Update Adapter limits with those from NVRAM
4535 * Comment: Don't need to do this. Target performance
4536 * parameters will never exceed the adapters limits.
4542 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4543 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4544 * @ioc: Pointer to a Adapter Strucutre
4545 * @portnum: IOC port number
4547 * Return: -EFAULT if read of config page header fails
4551 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4554 ConfigPageHeader_t header;
4556 /* Read the SCSI Device Page 1 header
4558 header.PageVersion = 0;
4559 header.PageLength = 0;
4560 header.PageNumber = 1;
4561 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4562 cfg.cfghdr.hdr = &header;
4564 cfg.pageAddr = portnum;
4565 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4568 if (mpt_config(ioc, &cfg) != 0)
4571 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4572 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4574 header.PageVersion = 0;
4575 header.PageLength = 0;
4576 header.PageNumber = 0;
4577 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4578 if (mpt_config(ioc, &cfg) != 0)
4581 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4582 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4584 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4585 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4587 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4588 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4592 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4594 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4595 * @ioc: Pointer to a Adapter Strucutre
4596 * @portnum: IOC port number
4600 * -EFAULT if read of config page header fails or data pointer not NULL
4601 * -ENOMEM if pci_alloc failed
4604 mpt_findImVolumes(MPT_ADAPTER *ioc)
4608 ConfigPageIoc2RaidVol_t *pIocRv;
4609 dma_addr_t ioc2_dma;
4611 ConfigPageHeader_t header;
4618 /* Read IOCP2 header then the page.
4620 header.PageVersion = 0;
4621 header.PageLength = 0;
4622 header.PageNumber = 2;
4623 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4624 cfg.cfghdr.hdr = &header;
4627 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4630 if (mpt_config(ioc, &cfg) != 0)
4633 if (header.PageLength == 0)
4636 iocpage2sz = header.PageLength * 4;
4637 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4641 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4642 cfg.physAddr = ioc2_dma;
4643 if (mpt_config(ioc, &cfg) != 0)
4646 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4647 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4649 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4654 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4656 /* Identify RAID Volume Id's */
4657 nVols = pIoc2->NumActiveVolumes;
4663 /* At least 1 RAID Volume
4665 pIocRv = pIoc2->RaidVolume;
4666 ioc->raid_data.isRaid = 0;
4667 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4668 vid = pIocRv->VolumeID;
4669 vbus = pIocRv->VolumeBus;
4670 vioc = pIocRv->VolumeIOC;
4675 ioc->raid_data.isRaid |= (1 << vid);
4677 /* Error! Always bus 0
4683 /* Identify Hidden Physical Disk Id's */
4684 nPhys = pIoc2->NumActivePhysDisks;
4686 /* No physical disks.
4689 mpt_read_ioc_pg_3(ioc);
4693 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4699 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4704 ConfigPageHeader_t header;
4705 dma_addr_t ioc3_dma;
4708 /* Free the old page
4710 kfree(ioc->raid_data.pIocPg3);
4711 ioc->raid_data.pIocPg3 = NULL;
4713 /* There is at least one physical disk.
4714 * Read and save IOC Page 3
4716 header.PageVersion = 0;
4717 header.PageLength = 0;
4718 header.PageNumber = 3;
4719 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4720 cfg.cfghdr.hdr = &header;
4723 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4726 if (mpt_config(ioc, &cfg) != 0)
4729 if (header.PageLength == 0)
4732 /* Read Header good, alloc memory
4734 iocpage3sz = header.PageLength * 4;
4735 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4739 /* Read the Page and save the data
4740 * into malloc'd memory.
4742 cfg.physAddr = ioc3_dma;
4743 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4744 if (mpt_config(ioc, &cfg) == 0) {
4745 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4747 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4748 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4752 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4758 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4762 ConfigPageHeader_t header;
4763 dma_addr_t ioc4_dma;
4766 /* Read and save IOC Page 4
4768 header.PageVersion = 0;
4769 header.PageLength = 0;
4770 header.PageNumber = 4;
4771 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4772 cfg.cfghdr.hdr = &header;
4775 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4778 if (mpt_config(ioc, &cfg) != 0)
4781 if (header.PageLength == 0)
4784 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4785 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4786 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4790 ioc4_dma = ioc->spi_data.IocPg4_dma;
4791 iocpage4sz = ioc->spi_data.IocPg4Sz;
4794 /* Read the Page into dma memory.
4796 cfg.physAddr = ioc4_dma;
4797 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4798 if (mpt_config(ioc, &cfg) == 0) {
4799 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4800 ioc->spi_data.IocPg4_dma = ioc4_dma;
4801 ioc->spi_data.IocPg4Sz = iocpage4sz;
4803 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4804 ioc->spi_data.pIocPg4 = NULL;
4809 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4813 ConfigPageHeader_t header;
4814 dma_addr_t ioc1_dma;
4818 /* Check the Coalescing Timeout in IOC Page 1
4820 header.PageVersion = 0;
4821 header.PageLength = 0;
4822 header.PageNumber = 1;
4823 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4824 cfg.cfghdr.hdr = &header;
4827 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4830 if (mpt_config(ioc, &cfg) != 0)
4833 if (header.PageLength == 0)
4836 /* Read Header good, alloc memory
4838 iocpage1sz = header.PageLength * 4;
4839 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4843 /* Read the Page and check coalescing timeout
4845 cfg.physAddr = ioc1_dma;
4846 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4847 if (mpt_config(ioc, &cfg) == 0) {
4849 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4850 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4851 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4853 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4856 if (tmp > MPT_COALESCING_TIMEOUT) {
4857 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4859 /* Write NVRAM and current
4862 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4863 if (mpt_config(ioc, &cfg) == 0) {
4864 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4865 ioc->name, MPT_COALESCING_TIMEOUT));
4867 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4868 if (mpt_config(ioc, &cfg) == 0) {
4869 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4870 ioc->name, MPT_COALESCING_TIMEOUT));
4872 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4877 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4883 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4887 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4892 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4894 * SendEventNotification - Send EventNotification (on or off) request
4896 * @ioc: Pointer to MPT_ADAPTER structure
4897 * @EvSwitch: Event switch flags
4900 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4902 EventNotification_t *evnp;
4904 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4906 devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4910 memset(evnp, 0, sizeof(*evnp));
4912 devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
4914 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4915 evnp->ChainOffset = 0;
4917 evnp->Switch = EvSwitch;
4919 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4924 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4926 * SendEventAck - Send EventAck request to MPT adapter.
4927 * @ioc: Pointer to MPT_ADAPTER structure
4928 * @evnp: Pointer to original EventNotification request
4931 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4935 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4936 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
4937 "request frame for Event=%x EventContext=%x EventData=%x!\n",
4938 ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
4939 le32_to_cpu(evnp->Data[0]));
4942 memset(pAck, 0, sizeof(*pAck));
4944 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4946 pAck->Function = MPI_FUNCTION_EVENT_ACK;
4947 pAck->ChainOffset = 0;
4949 pAck->Event = evnp->Event;
4950 pAck->EventContext = evnp->EventContext;
4952 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4957 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4959 * mpt_config - Generic function to issue config message
4960 * @ioc - Pointer to an adapter structure
4961 * @cfg - Pointer to a configuration structure. Struct contains
4962 * action, page address, direction, physical address
4963 * and pointer to a configuration page header
4964 * Page header is updated.
4966 * Returns 0 for success
4967 * -EPERM if not allowed due to ISR context
4968 * -EAGAIN if no msg frames currently available
4969 * -EFAULT for non-successful reply or no reply (timeout)
4972 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4975 ConfigExtendedPageHeader_t *pExtHdr = NULL;
4977 unsigned long flags;
4982 /* Prevent calling wait_event() (below), if caller happens
4983 * to be in ISR context, because that is fatal!
4985 in_isr = in_interrupt();
4987 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4992 /* Get and Populate a free Frame
4994 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4995 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
4999 pReq = (Config_t *)mf;
5000 pReq->Action = pCfg->action;
5002 pReq->ChainOffset = 0;
5003 pReq->Function = MPI_FUNCTION_CONFIG;
5005 /* Assume page type is not extended and clear "reserved" fields. */
5006 pReq->ExtPageLength = 0;
5007 pReq->ExtPageType = 0;
5010 for (ii=0; ii < 8; ii++)
5011 pReq->Reserved2[ii] = 0;
5013 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5014 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5015 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5016 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5018 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5019 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5020 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5021 pReq->ExtPageType = pExtHdr->ExtPageType;
5022 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5024 /* Page Length must be treated as a reserved field for the extended header. */
5025 pReq->Header.PageLength = 0;
5028 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5030 /* Add a SGE to the config request.
5033 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5035 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5037 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5038 flagsLength |= pExtHdr->ExtPageLength * 4;
5040 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5041 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5044 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5046 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5047 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5050 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5052 /* Append pCfg pointer to end of mf
5054 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5056 /* Initalize the timer
5058 init_timer(&pCfg->timer);
5059 pCfg->timer.data = (unsigned long) ioc;
5060 pCfg->timer.function = mpt_timer_expired;
5061 pCfg->wait_done = 0;
5063 /* Set the timer; ensure 10 second minimum */
5064 if (pCfg->timeout < 10)
5065 pCfg->timer.expires = jiffies + HZ*10;
5067 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5069 /* Add to end of Q, set timer and then issue this command */
5070 spin_lock_irqsave(&ioc->FreeQlock, flags);
5071 list_add_tail(&pCfg->linkage, &ioc->configQ);
5072 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5074 add_timer(&pCfg->timer);
5075 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5076 wait_event(mpt_waitq, pCfg->wait_done);
5078 /* mf has been freed - do not access */
5085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5087 * mpt_toolbox - Generic function to issue toolbox message
5088 * @ioc - Pointer to an adapter structure
5089 * @cfg - Pointer to a toolbox structure. Struct contains
5090 * action, page address, direction, physical address
5091 * and pointer to a configuration page header
5092 * Page header is updated.
5094 * Returns 0 for success
5095 * -EPERM if not allowed due to ISR context
5096 * -EAGAIN if no msg frames currently available
5097 * -EFAULT for non-successful reply or no reply (timeout)
5100 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5102 ToolboxIstwiReadWriteRequest_t *pReq;
5104 struct pci_dev *pdev;
5105 unsigned long flags;
5110 /* Prevent calling wait_event() (below), if caller happens
5111 * to be in ISR context, because that is fatal!
5113 in_isr = in_interrupt();
5115 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
5120 /* Get and Populate a free Frame
5122 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5123 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
5127 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
5128 pReq->Tool = pCfg->action;
5130 pReq->ChainOffset = 0;
5131 pReq->Function = MPI_FUNCTION_TOOLBOX;
5132 pReq->Reserved1 = 0;
5133 pReq->Reserved2 = 0;
5135 pReq->Flags = pCfg->dir;
5137 pReq->Reserved3 = 0;
5138 pReq->NumAddressBytes = 0x01;
5139 pReq->Reserved4 = 0;
5140 pReq->DataLength = cpu_to_le16(0x04);
5142 if (pdev->devfn & 1)
5143 pReq->DeviceAddr = 0xB2;
5145 pReq->DeviceAddr = 0xB0;
5149 pReq->Reserved5 = 0;
5151 /* Add a SGE to the config request.
5154 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
5156 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
5158 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
5159 ioc->name, pReq->Tool));
5161 /* Append pCfg pointer to end of mf
5163 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5165 /* Initalize the timer
5167 init_timer(&pCfg->timer);
5168 pCfg->timer.data = (unsigned long) ioc;
5169 pCfg->timer.function = mpt_timer_expired;
5170 pCfg->wait_done = 0;
5172 /* Set the timer; ensure 10 second minimum */
5173 if (pCfg->timeout < 10)
5174 pCfg->timer.expires = jiffies + HZ*10;
5176 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5178 /* Add to end of Q, set timer and then issue this command */
5179 spin_lock_irqsave(&ioc->FreeQlock, flags);
5180 list_add_tail(&pCfg->linkage, &ioc->configQ);
5181 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5183 add_timer(&pCfg->timer);
5184 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5185 wait_event(mpt_waitq, pCfg->wait_done);
5187 /* mf has been freed - do not access */
5194 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5196 * mpt_timer_expired - Call back for timer process.
5197 * Used only internal config functionality.
5198 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5201 mpt_timer_expired(unsigned long data)
5203 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5205 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5207 /* Perform a FW reload */
5208 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5209 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5211 /* No more processing.
5212 * Hard reset clean-up will wake up
5213 * process and free all resources.
5215 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5220 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5222 * mpt_ioc_reset - Base cleanup for hard reset
5223 * @ioc: Pointer to the adapter structure
5224 * @reset_phase: Indicates pre- or post-reset functionality
5226 * Remark: Free's resources with internally generated commands.
5229 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5232 unsigned long flags;
5234 dprintk((KERN_WARNING MYNAM
5235 ": IOC %s_reset routed to MPT base driver!\n",
5236 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5237 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5239 if (reset_phase == MPT_IOC_SETUP_RESET) {
5241 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5242 /* If the internal config Q is not empty -
5243 * delete timer. MF resources will be freed when
5244 * the FIFO's are primed.
5246 spin_lock_irqsave(&ioc->FreeQlock, flags);
5247 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5248 del_timer(&pCfg->timer);
5249 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5254 /* Search the configQ for internal commands.
5255 * Flush the Q, and wake up all suspended threads.
5257 spin_lock_irqsave(&ioc->FreeQlock, flags);
5258 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5259 list_del(&pCfg->linkage);
5261 pCfg->status = MPT_CONFIG_ERROR;
5262 pCfg->wait_done = 1;
5263 wake_up(&mpt_waitq);
5265 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5268 return 1; /* currently means nothing really */
5272 #ifdef CONFIG_PROC_FS /* { */
5273 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5275 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5279 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5281 * Returns 0 for success, non-zero for failure.
5284 procmpt_create(void)
5286 struct proc_dir_entry *ent;
5288 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5289 if (mpt_proc_root_dir == NULL)
5292 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5294 ent->read_proc = procmpt_summary_read;
5296 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5298 ent->read_proc = procmpt_version_read;
5303 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5305 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5307 * Returns 0 for success, non-zero for failure.
5310 procmpt_destroy(void)
5312 remove_proc_entry("version", mpt_proc_root_dir);
5313 remove_proc_entry("summary", mpt_proc_root_dir);
5314 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5317 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5319 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5320 * or from /proc/mpt/iocN/summary.
5321 * @buf: Pointer to area to write information
5322 * @start: Pointer to start pointer
5323 * @offset: Offset to start writing
5325 * @eof: Pointer to EOF integer
5328 * Returns number of characters written to process performing the read.
5331 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5341 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5345 list_for_each_entry(ioc, &ioc_list, list) {
5348 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5351 if ((out-buf) >= request)
5358 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5361 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5363 * procmpt_version_read - Handle read request from /proc/mpt/version.
5364 * @buf: Pointer to area to write information
5365 * @start: Pointer to start pointer
5366 * @offset: Offset to start writing
5368 * @eof: Pointer to EOF integer
5371 * Returns number of characters written to process performing the read.
5374 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5377 int scsi, fc, sas, lan, ctl, targ, dmp;
5381 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5382 len += sprintf(buf+len, " Fusion MPT base driver\n");
5384 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5385 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5387 if (MptCallbacks[ii]) {
5388 switch (MptDriverClass[ii]) {
5390 if (!scsi++) drvname = "SPI host";
5393 if (!fc++) drvname = "FC host";
5396 if (!sas++) drvname = "SAS host";
5399 if (!lan++) drvname = "LAN";
5402 if (!targ++) drvname = "SCSI target";
5405 if (!ctl++) drvname = "ioctl";
5410 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5414 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5417 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5419 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5420 * @buf: Pointer to area to write information
5421 * @start: Pointer to start pointer
5422 * @offset: Offset to start writing
5424 * @eof: Pointer to EOF integer
5427 * Returns number of characters written to process performing the read.
5430 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5432 MPT_ADAPTER *ioc = data;
5438 mpt_get_fw_exp_ver(expVer, ioc);
5440 len = sprintf(buf, "%s:", ioc->name);
5441 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5442 len += sprintf(buf+len, " (f/w download boot flag set)");
5443 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5444 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5446 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5447 ioc->facts.ProductID,
5449 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5450 if (ioc->facts.FWImageSize)
5451 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5452 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5453 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5454 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5456 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5457 ioc->facts.CurrentHostMfaHighAddr);
5458 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5459 ioc->facts.CurrentSenseBufferHighAddr);
5461 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5462 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5464 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5465 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5467 * Rounding UP to nearest 4-kB boundary here...
5469 sz = (ioc->req_sz * ioc->req_depth) + 128;
5470 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5471 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5472 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5473 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5474 4*ioc->facts.RequestFrameSize,
5475 ioc->facts.GlobalCredits);
5477 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5478 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5479 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5480 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5481 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5482 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5483 ioc->facts.CurReplyFrameSize,
5484 ioc->facts.ReplyQueueDepth);
5486 len += sprintf(buf+len, " MaxDevices = %d\n",
5487 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5488 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5491 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5492 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5494 ioc->facts.NumberOfPorts);
5495 if (ioc->bus_type == FC) {
5496 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5497 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5498 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5499 a[5], a[4], a[3], a[2], a[1], a[0]);
5501 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5502 ioc->fc_port_page0[p].WWNN.High,
5503 ioc->fc_port_page0[p].WWNN.Low,
5504 ioc->fc_port_page0[p].WWPN.High,
5505 ioc->fc_port_page0[p].WWPN.Low);
5509 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5512 #endif /* CONFIG_PROC_FS } */
5514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5516 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5519 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5520 sprintf(buf, " (Exp %02d%02d)",
5521 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5522 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5525 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5526 strcat(buf, " [MDBG]");
5530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5532 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5533 * @ioc: Pointer to MPT_ADAPTER structure
5534 * @buffer: Pointer to buffer where IOC summary info should be written
5535 * @size: Pointer to number of bytes we wrote (set by this routine)
5536 * @len: Offset at which to start writing in buffer
5537 * @showlan: Display LAN stuff?
5539 * This routine writes (english readable) ASCII text, which represents
5540 * a summary of IOC information, to a buffer.
5543 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5548 mpt_get_fw_exp_ver(expVer, ioc);
5551 * Shorter summary of attached ioc's...
5553 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5556 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5557 ioc->facts.FWVersion.Word,
5559 ioc->facts.NumberOfPorts,
5562 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5563 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5564 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5565 a[5], a[4], a[3], a[2], a[1], a[0]);
5569 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5571 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5575 y += sprintf(buffer+len+y, " (disabled)");
5577 y += sprintf(buffer+len+y, "\n");
5582 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5586 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5588 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5589 * Management call based on input arg values. If TaskMgmt fails,
5590 * return associated SCSI request.
5591 * @ioc: Pointer to MPT_ADAPTER structure
5592 * @sleepFlag: Indicates if sleep or schedule must be called.
5594 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5595 * or a non-interrupt thread. In the former, must not call schedule().
5597 * Remark: A return of -1 is a FATAL error case, as it means a
5598 * FW reload/initialization failed.
5600 * Returns 0 for SUCCESS or -1 if FAILED.
5603 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5606 unsigned long flags;
5608 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5610 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5611 printk("MF count 0x%x !\n", ioc->mfcnt);
5614 /* Reset the adapter. Prevent more than 1 call to
5615 * mpt_do_ioc_recovery at any instant in time.
5617 spin_lock_irqsave(&ioc->diagLock, flags);
5618 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5619 spin_unlock_irqrestore(&ioc->diagLock, flags);
5622 ioc->diagPending = 1;
5624 spin_unlock_irqrestore(&ioc->diagLock, flags);
5626 /* FIXME: If do_ioc_recovery fails, repeat....
5629 /* The SCSI driver needs to adjust timeouts on all current
5630 * commands prior to the diagnostic reset being issued.
5631 * Prevents timeouts occuring during a diagnostic reset...very bad.
5632 * For all other protocol drivers, this is a no-op.
5638 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5639 if (MptResetHandlers[ii]) {
5640 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5642 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5644 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5645 ioc->name, ioc->alt_ioc->name, ii));
5646 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5652 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5653 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5658 ioc->alt_ioc->reload_fw = 0;
5660 spin_lock_irqsave(&ioc->diagLock, flags);
5661 ioc->diagPending = 0;
5663 ioc->alt_ioc->diagPending = 0;
5664 spin_unlock_irqrestore(&ioc->diagLock, flags);
5666 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5671 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5673 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5678 case MPI_EVENT_NONE:
5681 case MPI_EVENT_LOG_DATA:
5684 case MPI_EVENT_STATE_CHANGE:
5685 ds = "State Change";
5687 case MPI_EVENT_UNIT_ATTENTION:
5688 ds = "Unit Attention";
5690 case MPI_EVENT_IOC_BUS_RESET:
5691 ds = "IOC Bus Reset";
5693 case MPI_EVENT_EXT_BUS_RESET:
5694 ds = "External Bus Reset";
5696 case MPI_EVENT_RESCAN:
5697 ds = "Bus Rescan Event";
5698 /* Ok, do we need to do anything here? As far as
5699 I can tell, this is when a new device gets added
5702 case MPI_EVENT_LINK_STATUS_CHANGE:
5703 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5704 ds = "Link Status(FAILURE) Change";
5706 ds = "Link Status(ACTIVE) Change";
5708 case MPI_EVENT_LOOP_STATE_CHANGE:
5709 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5710 ds = "Loop State(LIP) Change";
5711 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5712 ds = "Loop State(LPE) Change"; /* ??? */
5714 ds = "Loop State(LPB) Change"; /* ??? */
5716 case MPI_EVENT_LOGOUT:
5719 case MPI_EVENT_EVENT_CHANGE:
5721 ds = "Events(ON) Change";
5723 ds = "Events(OFF) Change";
5725 case MPI_EVENT_INTEGRATED_RAID:
5727 u8 ReasonCode = (u8)(evData0 >> 16);
5728 switch (ReasonCode) {
5729 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5730 ds = "Integrated Raid: Volume Created";
5732 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5733 ds = "Integrated Raid: Volume Deleted";
5735 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5736 ds = "Integrated Raid: Volume Settings Changed";
5738 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5739 ds = "Integrated Raid: Volume Status Changed";
5741 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5742 ds = "Integrated Raid: Volume Physdisk Changed";
5744 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5745 ds = "Integrated Raid: Physdisk Created";
5747 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5748 ds = "Integrated Raid: Physdisk Deleted";
5750 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5751 ds = "Integrated Raid: Physdisk Settings Changed";
5753 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5754 ds = "Integrated Raid: Physdisk Status Changed";
5756 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5757 ds = "Integrated Raid: Domain Validation Needed";
5759 case MPI_EVENT_RAID_RC_SMART_DATA :
5760 ds = "Integrated Raid; Smart Data";
5762 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5763 ds = "Integrated Raid: Replace Action Started";
5766 ds = "Integrated Raid";
5771 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5772 ds = "SCSI Device Status Change";
5774 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5776 u8 ReasonCode = (u8)(evData0 >> 16);
5777 switch (ReasonCode) {
5778 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5779 ds = "SAS Device Status Change: Added";
5781 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5782 ds = "SAS Device Status Change: Deleted";
5784 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5785 ds = "SAS Device Status Change: SMART Data";
5787 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5788 ds = "SAS Device Status Change: No Persistancy Added";
5791 ds = "SAS Device Status Change: Unknown";
5796 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5797 ds = "Bus Timer Expired";
5799 case MPI_EVENT_QUEUE_FULL:
5802 case MPI_EVENT_SAS_SES:
5803 ds = "SAS SES Event";
5805 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5806 ds = "Persistent Table Full";
5808 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5809 ds = "SAS PHY Link Status";
5811 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5812 ds = "SAS Discovery Error";
5816 * MPT base "custom" events may be added here...
5825 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5827 * ProcessEventNotification - Route a received EventNotificationReply to
5828 * all currently regeistered event handlers.
5829 * @ioc: Pointer to MPT_ADAPTER structure
5830 * @pEventReply: Pointer to EventNotification reply frame
5831 * @evHandlers: Pointer to integer, number of event handlers
5833 * Returns sum of event handlers return values.
5836 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5848 * Do platform normalization of values
5850 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5851 // evCtx = le32_to_cpu(pEventReply->EventContext);
5852 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5854 evData0 = le32_to_cpu(pEventReply->Data[0]);
5857 EventDescriptionStr(event, evData0, evStr);
5858 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5863 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5864 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5865 for (ii = 0; ii < evDataLen; ii++)
5866 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5871 * Do general / base driver event processing
5874 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5876 u8 evState = evData0 & 0xFF;
5878 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5880 /* Update EventState field in cached IocFacts */
5881 if (ioc->facts.Function) {
5882 ioc->facts.EventState = evState;
5891 * Should this event be logged? Events are written sequentially.
5892 * When buffer is full, start again at the top.
5894 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5897 idx = ioc->eventContext % ioc->eventLogSize;
5899 ioc->events[idx].event = event;
5900 ioc->events[idx].eventContext = ioc->eventContext;
5902 for (ii = 0; ii < 2; ii++) {
5904 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5906 ioc->events[idx].data[ii] = 0;
5909 ioc->eventContext++;
5914 * Call each currently registered protocol event handler.
5916 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5917 if (MptEvHandlers[ii]) {
5918 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5920 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5924 /* FIXME? Examine results here? */
5927 * If needed, send (a single) EventAck.
5929 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5930 devtprintk((MYIOC_s_WARN_FMT
5931 "EventAck required\n",ioc->name));
5932 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5933 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5938 *evHandlers = handlers;
5942 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5944 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5945 * @ioc: Pointer to MPT_ADAPTER structure
5946 * @log_info: U32 LogInfo reply word from the IOC
5948 * Refer to lsi/fc_log.h.
5951 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5953 static char *subcl_str[8] = {
5954 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5955 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5957 u8 subcl = (log_info >> 24) & 0x7;
5959 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
5960 ioc->name, log_info, subcl_str[subcl]);
5963 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5965 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5966 * @ioc: Pointer to MPT_ADAPTER structure
5967 * @mr: Pointer to MPT reply frame
5968 * @log_info: U32 LogInfo word from the IOC
5970 * Refer to lsi/sp_log.h.
5973 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5975 u32 info = log_info & 0x00FF0000;
5976 char *desc = "unknown";
5980 desc = "bug! MID not found";
5981 if (ioc->reload_fw == 0)
5986 desc = "Parity Error";
5990 desc = "ASYNC Outbound Overrun";
5994 desc = "SYNC Offset Error";
6002 desc = "Msg In Overflow";
6010 desc = "Outbound DMA Overrun";
6014 desc = "Task Management";
6018 desc = "Device Problem";
6022 desc = "Invalid Phase Change";
6026 desc = "Untagged Table Size";
6031 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6034 /* strings for sas loginfo */
6035 static char *originator_str[] = {
6040 static char *iop_code_str[] = {
6042 "Invalid SAS Address", /* 01h */
6044 "Invalid Page", /* 03h */
6046 "Task Terminated" /* 05h */
6048 static char *pl_code_str[] = {
6050 "Open Failure", /* 01h */
6051 "Invalid Scatter Gather List", /* 02h */
6052 "Wrong Relative Offset or Frame Length", /* 03h */
6053 "Frame Transfer Error", /* 04h */
6054 "Transmit Frame Connected Low", /* 05h */
6055 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6056 "SATA Read Log Receive Data Error", /* 07h */
6057 "SATA NCQ Fail All Commands After Error", /* 08h */
6058 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6059 "Receive Frame Invalid Message", /* 0Ah */
6060 "Receive Context Message Valid Error", /* 0Bh */
6061 "Receive Frame Current Frame Error", /* 0Ch */
6062 "SATA Link Down", /* 0Dh */
6063 "Discovery SATA Init W IOS", /* 0Eh */
6064 "Config Invalid Page", /* 0Fh */
6065 "Discovery SATA Init Timeout", /* 10h */
6068 "IO Not Yet Executed", /* 13h */
6069 "IO Executed", /* 14h */
6081 "Enclosure Management" /* 20h */
6084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6086 * mpt_sas_log_info - Log information returned from SAS IOC.
6087 * @ioc: Pointer to MPT_ADAPTER structure
6088 * @log_info: U32 LogInfo reply word from the IOC
6090 * Refer to lsi/mpi_log_sas.h.
6093 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6095 union loginfo_type {
6104 union loginfo_type sas_loginfo;
6105 char *code_desc = NULL;
6107 sas_loginfo.loginfo = log_info;
6108 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6109 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6111 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6112 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6113 code_desc = iop_code_str[sas_loginfo.dw.code];
6114 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6115 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6116 code_desc = pl_code_str[sas_loginfo.dw.code];
6119 if (code_desc != NULL)
6120 printk(MYIOC_s_INFO_FMT
6121 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6122 " SubCode(0x%04x)\n",
6125 originator_str[sas_loginfo.dw.originator],
6127 sas_loginfo.dw.subcode);
6129 printk(MYIOC_s_INFO_FMT
6130 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6131 " SubCode(0x%04x)\n",
6134 originator_str[sas_loginfo.dw.originator],
6135 sas_loginfo.dw.code,
6136 sas_loginfo.dw.subcode);
6139 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6141 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6142 * @ioc: Pointer to MPT_ADAPTER structure
6143 * @ioc_status: U32 IOCStatus word from IOC
6144 * @mf: Pointer to MPT request frame
6146 * Refer to lsi/mpi.h.
6149 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6151 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6155 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6156 desc = "Invalid Function";
6159 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6163 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6164 desc = "Invalid SGL";
6167 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6168 desc = "Internal Error";
6171 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6175 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6176 desc = "Insufficient Resources";
6179 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6180 desc = "Invalid Field";
6183 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6184 desc = "Invalid State";
6187 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6188 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6189 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6190 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6191 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6192 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6193 /* No message for Config IOCStatus values */
6196 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6197 /* No message for recovered error
6198 desc = "SCSI Recovered Error";
6202 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6203 desc = "SCSI Invalid Bus";
6206 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6207 desc = "SCSI Invalid TargetID";
6210 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6212 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6213 U8 cdb = pScsiReq->CDB[0];
6214 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6215 desc = "SCSI Device Not There";
6220 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6221 desc = "SCSI Data Overrun";
6224 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6225 /* This error is checked in scsi_io_done(). Skip.
6226 desc = "SCSI Data Underrun";
6230 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6231 desc = "SCSI I/O Data Error";
6234 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6235 desc = "SCSI Protocol Error";
6238 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6239 desc = "SCSI Task Terminated";
6242 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6243 desc = "SCSI Residual Mismatch";
6246 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6247 desc = "SCSI Task Management Failed";
6250 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6251 desc = "SCSI IOC Terminated";
6254 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6255 desc = "SCSI Ext Terminated";
6263 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6266 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6267 EXPORT_SYMBOL(mpt_attach);
6268 EXPORT_SYMBOL(mpt_detach);
6270 EXPORT_SYMBOL(mpt_resume);
6271 EXPORT_SYMBOL(mpt_suspend);
6273 EXPORT_SYMBOL(ioc_list);
6274 EXPORT_SYMBOL(mpt_proc_root_dir);
6275 EXPORT_SYMBOL(mpt_register);
6276 EXPORT_SYMBOL(mpt_deregister);
6277 EXPORT_SYMBOL(mpt_event_register);
6278 EXPORT_SYMBOL(mpt_event_deregister);
6279 EXPORT_SYMBOL(mpt_reset_register);
6280 EXPORT_SYMBOL(mpt_reset_deregister);
6281 EXPORT_SYMBOL(mpt_device_driver_register);
6282 EXPORT_SYMBOL(mpt_device_driver_deregister);
6283 EXPORT_SYMBOL(mpt_get_msg_frame);
6284 EXPORT_SYMBOL(mpt_put_msg_frame);
6285 EXPORT_SYMBOL(mpt_free_msg_frame);
6286 EXPORT_SYMBOL(mpt_add_sge);
6287 EXPORT_SYMBOL(mpt_send_handshake_request);
6288 EXPORT_SYMBOL(mpt_verify_adapter);
6289 EXPORT_SYMBOL(mpt_GetIocState);
6290 EXPORT_SYMBOL(mpt_print_ioc_summary);
6291 EXPORT_SYMBOL(mpt_lan_index);
6292 EXPORT_SYMBOL(mpt_stm_index);
6293 EXPORT_SYMBOL(mpt_HardResetHandler);
6294 EXPORT_SYMBOL(mpt_config);
6295 EXPORT_SYMBOL(mpt_toolbox);
6296 EXPORT_SYMBOL(mpt_findImVolumes);
6297 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6298 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6299 EXPORT_SYMBOL(mpt_free_fw_memory);
6300 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6303 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6305 * fusion_init - Fusion MPT base driver initialization routine.
6307 * Returns 0 for success, non-zero for failure.
6314 show_mptmod_ver(my_NAME, my_VERSION);
6315 printk(KERN_INFO COPYRIGHT "\n");
6317 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6318 MptCallbacks[i] = NULL;
6319 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6320 MptEvHandlers[i] = NULL;
6321 MptResetHandlers[i] = NULL;
6324 /* Register ourselves (mptbase) in order to facilitate
6325 * EventNotification handling.
6327 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6329 /* Register for hard reset handling callbacks.
6331 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6332 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6337 #ifdef CONFIG_PROC_FS
6338 (void) procmpt_create();
6343 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6345 * fusion_exit - Perform driver unload cleanup.
6347 * This routine frees all resources associated with each MPT adapter
6348 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6354 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6356 mpt_reset_deregister(mpt_base_index);
6358 #ifdef CONFIG_PROC_FS
6363 module_init(fusion_init);
6364 module_exit(fusion_exit);