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/version.h>
51 #include <linux/kernel.h>
52 #include <linux/module.h>
53 #include <linux/errno.h>
54 #include <linux/init.h>
55 #include <linux/slab.h>
56 #include <linux/types.h>
57 #include <linux/pci.h>
58 #include <linux/kdev_t.h>
59 #include <linux/blkdev.h>
60 #include <linux/delay.h>
61 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
62 #include <linux/dma-mapping.h>
68 #include <asm/irq.h> /* needed for __irq_itoa() proto */
73 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
74 #define my_NAME "Fusion MPT base driver"
75 #define my_VERSION MPT_LINUX_VERSION_COMMON
76 #define MYNAM "mptbase"
78 MODULE_AUTHOR(MODULEAUTHOR);
79 MODULE_DESCRIPTION(my_NAME);
80 MODULE_LICENSE("GPL");
86 static int mfcounter = 0;
87 #define PRINT_MF_COUNT 20000
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
94 int mpt_lan_index = -1;
95 int mpt_stm_index = -1;
97 struct proc_dir_entry *mpt_proc_root_dir;
99 #define WHOINIT_UNKNOWN 0xAA
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
105 /* Adapter link list */
107 /* Callback lookup table */
108 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
109 /* Protocol driver class lookup table */
110 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
111 /* Event handler lookup table */
112 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
113 /* Reset handler lookup table */
114 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
115 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
117 static int mpt_base_index = -1;
118 static int last_drv_idx = -1;
120 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
126 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
127 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
128 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
129 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
131 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
132 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
133 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
134 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
136 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
137 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
138 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
139 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
140 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
141 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
142 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
143 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
144 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
145 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
146 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
147 static int PrimeIocFifos(MPT_ADAPTER *ioc);
148 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
149 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
150 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
151 static int GetLanConfigPages(MPT_ADAPTER *ioc);
152 static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
153 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
154 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
155 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
156 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
157 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
158 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
159 static void mpt_timer_expired(unsigned long data);
160 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
161 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
162 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
163 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
165 #ifdef CONFIG_PROC_FS
166 static int procmpt_summary_read(char *buf, char **start, off_t offset,
167 int request, int *eof, void *data);
168 static int procmpt_version_read(char *buf, char **start, off_t offset,
169 int request, int *eof, void *data);
170 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
171 int request, int *eof, void *data);
173 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
175 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
176 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
177 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
178 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
179 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
180 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
182 /* module entry point */
183 static int __init fusion_init (void);
184 static void __exit fusion_exit (void);
186 #define CHIPREG_READ32(addr) readl_relaxed(addr)
187 #define CHIPREG_READ32_dmasync(addr) readl(addr)
188 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
189 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
190 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
193 pci_disable_io_access(struct pci_dev *pdev)
197 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
199 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
203 pci_enable_io_access(struct pci_dev *pdev)
207 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
209 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
213 * Process turbo (context) reply...
216 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
218 MPT_FRAME_HDR *mf = NULL;
219 MPT_FRAME_HDR *mr = NULL;
223 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
226 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
227 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
228 req_idx = pa & 0x0000FFFF;
229 cb_idx = (pa & 0x00FF0000) >> 16;
230 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
232 case MPI_CONTEXT_REPLY_TYPE_LAN:
233 cb_idx = mpt_lan_index;
235 * Blind set of mf to NULL here was fatal
236 * after lan_reply says "freeme"
237 * Fix sort of combined with an optimization here;
238 * added explicit check for case where lan_reply
239 * was just returning 1 and doing nothing else.
240 * For this case skip the callback, but set up
241 * proper mf value first here:-)
243 if ((pa & 0x58000000) == 0x58000000) {
244 req_idx = pa & 0x0000FFFF;
245 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
246 mpt_free_msg_frame(ioc, mf);
251 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
253 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
254 cb_idx = mpt_stm_index;
255 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
262 /* Check for (valid) IO callback! */
263 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
264 MptCallbacks[cb_idx] == NULL) {
265 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
266 __FUNCTION__, ioc->name, cb_idx);
270 if (MptCallbacks[cb_idx](ioc, mf, mr))
271 mpt_free_msg_frame(ioc, mf);
277 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
288 /* non-TURBO reply! Hmmm, something may be up...
289 * Newest turbo reply mechanism; get address
290 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
293 /* Map DMA address of reply header to cpu address.
294 * pa is 32 bits - but the dma address may be 32 or 64 bits
295 * get offset based only only the low addresses
298 reply_dma_low = (pa <<= 1);
299 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
300 (reply_dma_low - ioc->reply_frames_low_dma));
302 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
303 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
304 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
306 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
307 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
308 DBG_DUMP_REPLY_FRAME(mr)
310 /* Check/log IOC log info
312 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
313 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
314 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
315 if (ioc->bus_type == FC)
316 mpt_fc_log_info(ioc, log_info);
317 else if (ioc->bus_type == SCSI)
318 mpt_sp_log_info(ioc, log_info);
319 else if (ioc->bus_type == SAS)
320 mpt_sas_log_info(ioc, log_info);
322 if (ioc_stat & MPI_IOCSTATUS_MASK) {
323 if (ioc->bus_type == SCSI &&
324 cb_idx != mpt_stm_index &&
325 cb_idx != mpt_lan_index)
326 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
330 /* Check for (valid) IO callback! */
331 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
332 MptCallbacks[cb_idx] == NULL) {
333 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
334 __FUNCTION__, ioc->name, cb_idx);
339 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
342 /* Flush (non-TURBO) reply with a WRITE! */
343 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
346 mpt_free_msg_frame(ioc, mf);
350 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
352 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
353 * @irq: irq number (not used)
354 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
355 * @r: pt_regs pointer (not used)
357 * This routine is registered via the request_irq() kernel API call,
358 * and handles all interrupts generated from a specific MPT adapter
359 * (also referred to as a IO Controller or IOC).
360 * This routine must clear the interrupt from the adapter and does
361 * so by reading the reply FIFO. Multiple replies may be processed
362 * per single call to this routine.
364 * This routine handles register-level access of the adapter but
365 * dispatches (calls) a protocol-specific callback routine to handle
366 * the protocol-specific details of the MPT request completion.
369 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
371 MPT_ADAPTER *ioc = bus_id;
375 * Drain the reply FIFO!
378 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
379 if (pa == 0xFFFFFFFF)
381 else if (pa & MPI_ADDRESS_REPLY_A_BIT)
384 mpt_turbo_reply(ioc, pa);
390 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
392 * mpt_base_reply - MPT base driver's callback routine; all base driver
393 * "internal" request/reply processing is routed here.
394 * Currently used for EventNotification and EventAck handling.
395 * @ioc: Pointer to MPT_ADAPTER structure
396 * @mf: Pointer to original MPT request frame
397 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
399 * Returns 1 indicating original alloc'd request frame ptr
400 * should be freed, or 0 if it shouldn't.
403 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
408 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
410 #if defined(MPT_DEBUG_MSG_FRAME)
411 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
412 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
413 DBG_DUMP_REQUEST_FRAME_HDR(mf)
417 func = reply->u.hdr.Function;
418 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
421 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
422 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
426 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
427 if (results != evHandlers) {
428 /* CHECKME! Any special handling needed here? */
429 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
430 ioc->name, evHandlers, results));
434 * Hmmm... It seems that EventNotificationReply is an exception
435 * to the rule of one reply per request.
437 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
439 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
440 ioc->name, pEvReply));
442 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
443 ioc->name, pEvReply));
446 #ifdef CONFIG_PROC_FS
447 // LogEvent(ioc, pEvReply);
450 } else if (func == MPI_FUNCTION_EVENT_ACK) {
451 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
453 } else if (func == MPI_FUNCTION_CONFIG ||
454 func == MPI_FUNCTION_TOOLBOX) {
458 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
459 ioc->name, mf, reply));
461 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
464 /* disable timer and remove from linked list */
465 del_timer(&pCfg->timer);
467 spin_lock_irqsave(&ioc->FreeQlock, flags);
468 list_del(&pCfg->linkage);
469 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
472 * If IOC Status is SUCCESS, save the header
473 * and set the status code to GOOD.
475 pCfg->status = MPT_CONFIG_ERROR;
477 ConfigReply_t *pReply = (ConfigReply_t *)reply;
480 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
481 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
482 status, le32_to_cpu(pReply->IOCLogInfo)));
484 pCfg->status = status;
485 if (status == MPI_IOCSTATUS_SUCCESS) {
486 if ((pReply->Header.PageType &
487 MPI_CONFIG_PAGETYPE_MASK) ==
488 MPI_CONFIG_PAGETYPE_EXTENDED) {
489 pCfg->cfghdr.ehdr->ExtPageLength =
490 le16_to_cpu(pReply->ExtPageLength);
491 pCfg->cfghdr.ehdr->ExtPageType =
494 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
496 /* If this is a regular header, save PageLength. */
497 /* LMP Do this better so not using a reserved field! */
498 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
499 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
500 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
505 * Wake up the original calling thread
510 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
511 /* we should be always getting a reply frame */
512 memcpy(ioc->persist_reply_frame, reply,
513 min(MPT_DEFAULT_FRAME_SIZE,
514 4*reply->u.reply.MsgLength));
515 del_timer(&ioc->persist_timer);
516 ioc->persist_wait_done = 1;
519 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
524 * Conditionally tell caller to free the original
525 * EventNotification/EventAck/unexpected request frame!
530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
532 * mpt_register - Register protocol-specific main callback handler.
533 * @cbfunc: callback function pointer
534 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
536 * This routine is called by a protocol-specific driver (SCSI host,
537 * LAN, SCSI target) to register it's reply callback routine. Each
538 * protocol-specific driver must do this before it will be able to
539 * use any IOC resources, such as obtaining request frames.
541 * NOTES: The SCSI protocol driver currently calls this routine thrice
542 * in order to register separate callbacks; one for "normal" SCSI IO;
543 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
545 * Returns a positive integer valued "handle" in the
546 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
547 * Any non-positive return value (including zero!) should be considered
548 * an error by the caller.
551 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
558 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
559 * (slot/handle 0 is reserved!)
561 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
562 if (MptCallbacks[i] == NULL) {
563 MptCallbacks[i] = cbfunc;
564 MptDriverClass[i] = dclass;
565 MptEvHandlers[i] = NULL;
574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
576 * mpt_deregister - Deregister a protocol drivers resources.
577 * @cb_idx: previously registered callback handle
579 * Each protocol-specific driver should call this routine when it's
580 * module is unloaded.
583 mpt_deregister(int cb_idx)
585 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
586 MptCallbacks[cb_idx] = NULL;
587 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
588 MptEvHandlers[cb_idx] = NULL;
594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
596 * mpt_event_register - Register protocol-specific event callback
598 * @cb_idx: previously registered (via mpt_register) callback handle
599 * @ev_cbfunc: callback function
601 * This routine can be called by one or more protocol-specific drivers
602 * if/when they choose to be notified of MPT events.
604 * Returns 0 for success.
607 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
609 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
612 MptEvHandlers[cb_idx] = ev_cbfunc;
616 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
618 * mpt_event_deregister - Deregister protocol-specific event callback
620 * @cb_idx: previously registered callback handle
622 * Each protocol-specific driver should call this routine
623 * when it does not (or can no longer) handle events,
624 * or when it's module is unloaded.
627 mpt_event_deregister(int cb_idx)
629 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
632 MptEvHandlers[cb_idx] = NULL;
635 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
637 * mpt_reset_register - Register protocol-specific IOC reset handler.
638 * @cb_idx: previously registered (via mpt_register) callback handle
639 * @reset_func: reset function
641 * This routine can be called by one or more protocol-specific drivers
642 * if/when they choose to be notified of IOC resets.
644 * Returns 0 for success.
647 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
649 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
652 MptResetHandlers[cb_idx] = reset_func;
656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
658 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
659 * @cb_idx: previously registered callback handle
661 * Each protocol-specific driver should call this routine
662 * when it does not (or can no longer) handle IOC reset handling,
663 * or when it's module is unloaded.
666 mpt_reset_deregister(int cb_idx)
668 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
671 MptResetHandlers[cb_idx] = NULL;
674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
676 * mpt_device_driver_register - Register device driver hooks
679 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
683 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
687 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
689 /* call per pci device probe entry point */
690 list_for_each_entry(ioc, &ioc_list, list) {
691 if(dd_cbfunc->probe) {
692 dd_cbfunc->probe(ioc->pcidev,
693 ioc->pcidev->driver->id_table);
700 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
702 * mpt_device_driver_deregister - DeRegister device driver hooks
705 mpt_device_driver_deregister(int cb_idx)
707 struct mpt_pci_driver *dd_cbfunc;
710 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
713 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
715 list_for_each_entry(ioc, &ioc_list, list) {
716 if (dd_cbfunc->remove)
717 dd_cbfunc->remove(ioc->pcidev);
720 MptDeviceDriverHandlers[cb_idx] = NULL;
724 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
726 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
727 * allocated per MPT adapter.
728 * @handle: Handle of registered MPT protocol driver
729 * @ioc: Pointer to MPT adapter structure
731 * Returns pointer to a MPT request frame or %NULL if none are available
732 * or IOC is not active.
735 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
739 u16 req_idx; /* Request index */
741 /* validate handle and ioc identifier */
745 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
748 /* If interrupts are not attached, do not return a request frame */
752 spin_lock_irqsave(&ioc->FreeQlock, flags);
753 if (!list_empty(&ioc->FreeQ)) {
756 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
757 u.frame.linkage.list);
758 list_del(&mf->u.frame.linkage.list);
759 mf->u.frame.linkage.arg1 = 0;
760 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
761 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
763 req_idx = req_offset / ioc->req_sz;
764 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
765 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
766 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
773 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
777 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
779 if (mfcounter == PRINT_MF_COUNT)
780 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
783 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
784 ioc->name, handle, ioc->id, mf));
788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
790 * mpt_put_msg_frame - Send a protocol specific MPT request frame
792 * @handle: Handle of registered MPT protocol driver
793 * @ioc: Pointer to MPT adapter structure
794 * @mf: Pointer to MPT request frame
796 * This routine posts a MPT request frame to the request post FIFO of a
797 * specific MPT adapter.
800 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
804 u16 req_idx; /* Request index */
806 /* ensure values are reset properly! */
807 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
808 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
810 req_idx = req_offset / ioc->req_sz;
811 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
812 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
814 #ifdef MPT_DEBUG_MSG_FRAME
816 u32 *m = mf->u.frame.hwhdr.__hdr;
819 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
821 n = ioc->req_sz/4 - 1;
824 for (ii=0; ii<=n; ii++) {
825 if (ii && ((ii%8)==0))
826 printk("\n" KERN_INFO " ");
827 printk(" %08x", le32_to_cpu(m[ii]));
833 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
834 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]));
835 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
840 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
841 * @handle: Handle of registered MPT protocol driver
842 * @ioc: Pointer to MPT adapter structure
843 * @mf: Pointer to MPT request frame
845 * This routine places a MPT request frame back on the MPT adapter's
849 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
853 /* Put Request back on FreeQ! */
854 spin_lock_irqsave(&ioc->FreeQlock, flags);
855 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
856 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
860 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
863 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
865 * mpt_add_sge - Place a simple SGE at address pAddr.
866 * @pAddr: virtual address for SGE
867 * @flagslength: SGE flags and data transfer length
868 * @dma_addr: Physical address
870 * This routine places a MPT request frame back on the MPT adapter's
874 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
876 if (sizeof(dma_addr_t) == sizeof(u64)) {
877 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
878 u32 tmp = dma_addr & 0xFFFFFFFF;
880 pSge->FlagsLength = cpu_to_le32(flagslength);
881 pSge->Address.Low = cpu_to_le32(tmp);
882 tmp = (u32) ((u64)dma_addr >> 32);
883 pSge->Address.High = cpu_to_le32(tmp);
886 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
887 pSge->FlagsLength = cpu_to_le32(flagslength);
888 pSge->Address = cpu_to_le32(dma_addr);
892 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
894 * mpt_send_handshake_request - Send MPT request via doorbell
896 * @handle: Handle of registered MPT protocol driver
897 * @ioc: Pointer to MPT adapter structure
898 * @reqBytes: Size of the request in bytes
899 * @req: Pointer to MPT request frame
900 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
902 * This routine is used exclusively to send MptScsiTaskMgmt
903 * requests since they are required to be sent via doorbell handshake.
905 * NOTE: It is the callers responsibility to byte-swap fields in the
906 * request which are greater than 1 byte in size.
908 * Returns 0 for success, non-zero for failure.
911 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
917 /* State is known to be good upon entering
918 * this function so issue the bus reset
923 * Emulate what mpt_put_msg_frame() does /wrt to sanity
924 * setting cb_idx/req_idx. But ONLY if this request
925 * is in proper (pre-alloc'd) request buffer range...
927 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
928 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
929 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
930 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
931 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
934 /* Make sure there are no doorbells */
935 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
937 CHIPREG_WRITE32(&ioc->chip->Doorbell,
938 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
939 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
941 /* Wait for IOC doorbell int */
942 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
946 /* Read doorbell and check for active bit */
947 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
950 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
953 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
955 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
959 /* Send request via doorbell handshake */
960 req_as_bytes = (u8 *) req;
961 for (ii = 0; ii < reqBytes/4; ii++) {
964 word = ((req_as_bytes[(ii*4) + 0] << 0) |
965 (req_as_bytes[(ii*4) + 1] << 8) |
966 (req_as_bytes[(ii*4) + 2] << 16) |
967 (req_as_bytes[(ii*4) + 3] << 24));
968 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
969 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
975 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
980 /* Make sure there are no doorbells */
981 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
986 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
988 * mpt_host_page_access_control - provides mechanism for the host
989 * driver to control the IOC's Host Page Buffer access.
990 * @ioc: Pointer to MPT adapter structure
991 * @access_control_value: define bits below
993 * Access Control Value - bits[15:12]
995 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
996 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
997 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
999 * Returns 0 for success, non-zero for failure.
1003 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1007 /* return if in use */
1008 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1009 & MPI_DOORBELL_ACTIVE)
1012 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1014 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1015 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1016 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1017 (access_control_value<<12)));
1019 /* Wait for IOC to clear Doorbell Status bit */
1020 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1028 * mpt_host_page_alloc - allocate system memory for the fw
1029 * If we already allocated memory in past, then resend the same pointer.
1030 * ioc@: Pointer to pointer to IOC adapter
1031 * ioc_init@: Pointer to ioc init config page
1033 * Returns 0 for success, non-zero for failure.
1036 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1040 u32 host_page_buffer_sz=0;
1042 if(!ioc->HostPageBuffer) {
1044 host_page_buffer_sz =
1045 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1047 if(!host_page_buffer_sz)
1048 return 0; /* fw doesn't need any host buffers */
1050 /* spin till we get enough memory */
1051 while(host_page_buffer_sz > 0) {
1053 if((ioc->HostPageBuffer = pci_alloc_consistent(
1055 host_page_buffer_sz,
1056 &ioc->HostPageBuffer_dma)) != NULL) {
1058 dinitprintk((MYIOC_s_INFO_FMT
1059 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1061 ioc->HostPageBuffer,
1062 ioc->HostPageBuffer_dma,
1063 host_page_buffer_sz));
1064 ioc->alloc_total += host_page_buffer_sz;
1065 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1069 host_page_buffer_sz -= (4*1024);
1073 if(!ioc->HostPageBuffer) {
1074 printk(MYIOC_s_ERR_FMT
1075 "Failed to alloc memory for host_page_buffer!\n",
1080 psge = (char *)&ioc_init->HostPageBufferSGE;
1081 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1082 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1083 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1084 MPI_SGE_FLAGS_HOST_TO_IOC |
1085 MPI_SGE_FLAGS_END_OF_BUFFER;
1086 if (sizeof(dma_addr_t) == sizeof(u64)) {
1087 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1089 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1090 flags_length |= ioc->HostPageBuffer_sz;
1091 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1092 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1097 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1099 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1100 * the associated MPT adapter structure.
1101 * @iocid: IOC unique identifier (integer)
1102 * @iocpp: Pointer to pointer to IOC adapter
1104 * Returns iocid and sets iocpp.
1107 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1111 list_for_each_entry(ioc,&ioc_list,list) {
1112 if (ioc->id == iocid) {
1122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1124 * mpt_attach - Install a PCI intelligent MPT adapter.
1125 * @pdev: Pointer to pci_dev structure
1127 * This routine performs all the steps necessary to bring the IOC of
1128 * a MPT adapter to a OPERATIONAL state. This includes registering
1129 * memory regions, registering the interrupt, and allocating request
1130 * and reply memory pools.
1132 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1135 * Returns 0 for success, non-zero for failure.
1137 * TODO: Add support for polled controllers
1140 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1144 unsigned long mem_phys;
1152 static int mpt_ids = 0;
1153 #ifdef CONFIG_PROC_FS
1154 struct proc_dir_entry *dent, *ent;
1157 if (pci_enable_device(pdev))
1160 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1162 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1163 dprintk((KERN_INFO MYNAM
1164 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1165 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1166 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1170 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1171 dprintk((KERN_INFO MYNAM
1172 ": Using 64 bit consistent mask\n"));
1174 dprintk((KERN_INFO MYNAM
1175 ": Not using 64 bit consistent mask\n"));
1177 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1179 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1182 memset(ioc, 0, sizeof(MPT_ADAPTER));
1183 ioc->alloc_total = sizeof(MPT_ADAPTER);
1184 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1185 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1188 ioc->diagPending = 0;
1189 spin_lock_init(&ioc->diagLock);
1191 /* Initialize the event logging.
1193 ioc->eventTypes = 0; /* None */
1194 ioc->eventContext = 0;
1195 ioc->eventLogSize = 0;
1202 ioc->cached_fw = NULL;
1204 /* Initilize SCSI Config Data structure
1206 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1208 /* Initialize the running configQ head.
1210 INIT_LIST_HEAD(&ioc->configQ);
1212 /* Find lookup slot. */
1213 INIT_LIST_HEAD(&ioc->list);
1214 ioc->id = mpt_ids++;
1216 mem_phys = msize = 0;
1218 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1219 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1220 /* Get I/O space! */
1221 port = pci_resource_start(pdev, ii);
1222 psize = pci_resource_len(pdev,ii);
1225 mem_phys = pci_resource_start(pdev, ii);
1226 msize = pci_resource_len(pdev,ii);
1230 ioc->mem_size = msize;
1232 if (ii == DEVICE_COUNT_RESOURCE) {
1233 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1238 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1239 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1242 /* Get logical ptr for PciMem0 space */
1243 /*mem = ioremap(mem_phys, msize);*/
1244 mem = ioremap(mem_phys, 0x100);
1246 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1251 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1253 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1254 &ioc->facts, &ioc->pfacts[0]));
1256 ioc->mem_phys = mem_phys;
1257 ioc->chip = (SYSIF_REGS __iomem *)mem;
1259 /* Save Port IO values in case we need to do downloadboot */
1261 u8 *pmem = (u8*)port;
1262 ioc->pio_mem_phys = port;
1263 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1266 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1267 ioc->prod_name = "LSIFC909";
1270 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1271 ioc->prod_name = "LSIFC929";
1274 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1275 ioc->prod_name = "LSIFC919";
1278 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1279 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1281 if (revision < XL_929) {
1282 ioc->prod_name = "LSIFC929X";
1283 /* 929X Chip Fix. Set Split transactions level
1284 * for PCIX. Set MOST bits to zero.
1286 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1288 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1290 ioc->prod_name = "LSIFC929XL";
1291 /* 929XL Chip Fix. Set MMRBC to 0x08.
1293 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1295 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1298 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1299 ioc->prod_name = "LSIFC919X";
1301 /* 919X Chip Fix. Set Split transactions level
1302 * for PCIX. Set MOST bits to zero.
1304 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1306 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1308 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1309 ioc->prod_name = "LSIFC939X";
1311 ioc->errata_flag_1064 = 1;
1313 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1314 ioc->prod_name = "LSIFC949X";
1316 ioc->errata_flag_1064 = 1;
1318 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1319 ioc->prod_name = "LSI53C1030";
1320 ioc->bus_type = SCSI;
1321 /* 1030 Chip Fix. Disable Split transactions
1322 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1324 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1325 if (revision < C0_1030) {
1326 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1328 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1331 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1332 ioc->prod_name = "LSI53C1035";
1333 ioc->bus_type = SCSI;
1335 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1336 ioc->prod_name = "LSISAS1064";
1337 ioc->bus_type = SAS;
1338 ioc->errata_flag_1064 = 1;
1340 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
1341 ioc->prod_name = "LSISAS1066";
1342 ioc->bus_type = SAS;
1343 ioc->errata_flag_1064 = 1;
1345 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1346 ioc->prod_name = "LSISAS1068";
1347 ioc->bus_type = SAS;
1348 ioc->errata_flag_1064 = 1;
1350 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1351 ioc->prod_name = "LSISAS1064E";
1352 ioc->bus_type = SAS;
1354 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
1355 ioc->prod_name = "LSISAS1066E";
1356 ioc->bus_type = SAS;
1358 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1359 ioc->prod_name = "LSISAS1068E";
1360 ioc->bus_type = SAS;
1363 if (ioc->errata_flag_1064)
1364 pci_disable_io_access(pdev);
1366 sprintf(ioc->name, "ioc%d", ioc->id);
1368 spin_lock_init(&ioc->FreeQlock);
1371 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1373 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1375 /* Set lookup ptr. */
1376 list_add_tail(&ioc->list, &ioc_list);
1380 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1384 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1385 ioc->name, pdev->irq);
1387 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1388 ioc->name, __irq_itoa(pdev->irq));
1390 list_del(&ioc->list);
1396 ioc->pci_irq = pdev->irq;
1398 pci_set_master(pdev); /* ?? */
1399 pci_set_drvdata(pdev, ioc);
1402 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1404 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1408 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1410 mpt_detect_bound_ports(ioc, pdev);
1412 if ((r = mpt_do_ioc_recovery(ioc,
1413 MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1414 printk(KERN_WARNING MYNAM
1415 ": WARNING - %s did not initialize properly! (%d)\n",
1418 list_del(&ioc->list);
1419 free_irq(ioc->pci_irq, ioc);
1422 pci_set_drvdata(pdev, NULL);
1426 /* call per device driver probe entry point */
1427 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1428 if(MptDeviceDriverHandlers[ii] &&
1429 MptDeviceDriverHandlers[ii]->probe) {
1430 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1434 #ifdef CONFIG_PROC_FS
1436 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1438 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1440 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1442 ent->read_proc = procmpt_iocinfo_read;
1445 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1447 ent->read_proc = procmpt_summary_read;
1456 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1458 * mpt_detach - Remove a PCI intelligent MPT adapter.
1459 * @pdev: Pointer to pci_dev structure
1464 mpt_detach(struct pci_dev *pdev)
1466 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1470 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1471 remove_proc_entry(pname, NULL);
1472 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1473 remove_proc_entry(pname, NULL);
1474 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1475 remove_proc_entry(pname, NULL);
1477 /* call per device driver remove entry point */
1478 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1479 if(MptDeviceDriverHandlers[ii] &&
1480 MptDeviceDriverHandlers[ii]->remove) {
1481 MptDeviceDriverHandlers[ii]->remove(pdev);
1485 /* Disable interrupts! */
1486 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1489 synchronize_irq(pdev->irq);
1491 /* Clear any lingering interrupt */
1492 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1494 CHIPREG_READ32(&ioc->chip->IntStatus);
1496 mpt_adapter_dispose(ioc);
1498 pci_set_drvdata(pdev, NULL);
1501 /**************************************************************************
1505 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1507 * mpt_suspend - Fusion MPT base driver suspend routine.
1512 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1515 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1517 device_state=pci_choose_state(pdev, state);
1519 printk(MYIOC_s_INFO_FMT
1520 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1521 ioc->name, pdev, pci_name(pdev), device_state);
1523 pci_save_state(pdev);
1525 /* put ioc into READY_STATE */
1526 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1527 printk(MYIOC_s_ERR_FMT
1528 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1531 /* disable interrupts */
1532 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1535 /* Clear any lingering interrupt */
1536 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1538 pci_disable_device(pdev);
1539 pci_set_power_state(pdev, device_state);
1544 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1546 * mpt_resume - Fusion MPT base driver resume routine.
1551 mpt_resume(struct pci_dev *pdev)
1553 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1554 u32 device_state = pdev->current_state;
1558 printk(MYIOC_s_INFO_FMT
1559 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1560 ioc->name, pdev, pci_name(pdev), device_state);
1562 pci_set_power_state(pdev, 0);
1563 pci_restore_state(pdev);
1564 pci_enable_device(pdev);
1566 /* enable interrupts */
1567 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1570 /* F/W not running */
1571 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1572 /* enable domain validation flags */
1573 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1574 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1578 printk(MYIOC_s_INFO_FMT
1579 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1581 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1582 CHIPREG_READ32(&ioc->chip->Doorbell));
1584 /* bring ioc to operational state */
1585 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1586 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1587 printk(MYIOC_s_INFO_FMT
1588 "pci-resume: Cannot recover, error:[%x]\n",
1589 ioc->name, recovery_state);
1591 printk(MYIOC_s_INFO_FMT
1592 "pci-resume: success\n", ioc->name);
1599 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1601 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1602 * @ioc: Pointer to MPT adapter structure
1603 * @reason: Event word / reason
1604 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1606 * This routine performs all the steps necessary to bring the IOC
1607 * to a OPERATIONAL state.
1609 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1614 * -1 if failed to get board READY
1615 * -2 if READY but IOCFacts Failed
1616 * -3 if READY but PrimeIOCFifos Failed
1617 * -4 if READY but IOCInit Failed
1620 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1622 int hard_reset_done = 0;
1623 int alt_ioc_ready = 0;
1629 int reset_alt_ioc_active = 0;
1631 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1632 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1634 /* Disable reply interrupts (also blocks FreeQ) */
1635 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1639 if (ioc->alt_ioc->active)
1640 reset_alt_ioc_active = 1;
1642 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1643 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1644 ioc->alt_ioc->active = 0;
1648 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1651 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1652 if (hard_reset_done == -4) {
1653 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1656 if (reset_alt_ioc_active && ioc->alt_ioc) {
1657 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1658 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1659 ioc->alt_ioc->name));
1660 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1661 ioc->alt_ioc->active = 1;
1665 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1671 /* hard_reset_done = 0 if a soft reset was performed
1672 * and 1 if a hard reset was performed.
1674 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1675 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1678 printk(KERN_WARNING MYNAM
1679 ": alt-%s: Not ready WARNING!\n",
1680 ioc->alt_ioc->name);
1683 for (ii=0; ii<5; ii++) {
1684 /* Get IOC facts! Allow 5 retries */
1685 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1691 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1693 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1694 MptDisplayIocCapabilities(ioc);
1697 if (alt_ioc_ready) {
1698 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1699 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1700 /* Retry - alt IOC was initialized once
1702 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1705 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1707 reset_alt_ioc_active = 0;
1708 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1709 MptDisplayIocCapabilities(ioc->alt_ioc);
1713 /* Prime reply & request queues!
1714 * (mucho alloc's) Must be done prior to
1715 * init as upper addresses are needed for init.
1716 * If fails, continue with alt-ioc processing
1718 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1721 /* May need to check/upload firmware & data here!
1722 * If fails, continue with alt-ioc processing
1724 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1727 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1728 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1729 ioc->alt_ioc->name, rc);
1731 reset_alt_ioc_active = 0;
1734 if (alt_ioc_ready) {
1735 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1737 reset_alt_ioc_active = 0;
1738 printk(KERN_WARNING MYNAM
1739 ": alt-%s: (%d) init failure WARNING!\n",
1740 ioc->alt_ioc->name, rc);
1744 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1745 if (ioc->upload_fw) {
1746 ddlprintk((MYIOC_s_INFO_FMT
1747 "firmware upload required!\n", ioc->name));
1749 /* Controller is not operational, cannot do upload
1752 rc = mpt_do_upload(ioc, sleepFlag);
1754 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1756 * Maintain only one pointer to FW memory
1757 * so there will not be two attempt to
1758 * downloadboot onboard dual function
1759 * chips (mpt_adapter_disable,
1762 ioc->cached_fw = NULL;
1763 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1764 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1767 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1775 /* Enable! (reply interrupt) */
1776 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1780 if (reset_alt_ioc_active && ioc->alt_ioc) {
1781 /* (re)Enable alt-IOC! (reply interrupt) */
1782 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1783 ioc->alt_ioc->name));
1784 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1785 ioc->alt_ioc->active = 1;
1788 /* Enable MPT base driver management of EventNotification
1789 * and EventAck handling.
1791 if ((ret == 0) && (!ioc->facts.EventState))
1792 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1794 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1795 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1797 /* Add additional "reason" check before call to GetLanConfigPages
1798 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1799 * recursive scenario; GetLanConfigPages times out, timer expired
1800 * routine calls HardResetHandler, which calls into here again,
1801 * and we try GetLanConfigPages again...
1803 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1804 if (ioc->bus_type == SAS) {
1806 /* clear persistency table */
1807 if(ioc->facts.IOCExceptions &
1808 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1809 ret = mptbase_sas_persist_operation(ioc,
1810 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1817 mpt_findImVolumes(ioc);
1819 } else if (ioc->bus_type == FC) {
1821 * Pre-fetch FC port WWN and stuff...
1822 * (FCPortPage0_t stuff)
1824 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1825 (void) GetFcPortPage0(ioc, ii);
1828 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1829 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1831 * Pre-fetch the ports LAN MAC address!
1832 * (LANPage1_t stuff)
1834 (void) GetLanConfigPages(ioc);
1837 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1838 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1839 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1844 /* Get NVRAM and adapter maximums from SPP 0 and 2
1846 mpt_GetScsiPortSettings(ioc, 0);
1848 /* Get version and length of SDP 1
1850 mpt_readScsiDevicePageHeaders(ioc, 0);
1854 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1855 mpt_findImVolumes(ioc);
1857 /* Check, and possibly reset, the coalescing value
1859 mpt_read_ioc_pg_1(ioc);
1861 mpt_read_ioc_pg_4(ioc);
1864 GetIoUnitPage2(ioc);
1868 * Call each currently registered protocol IOC reset handler
1869 * with post-reset indication.
1870 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1871 * MptResetHandlers[] registered yet.
1873 if (hard_reset_done) {
1875 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1876 if ((ret == 0) && MptResetHandlers[ii]) {
1877 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1879 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1883 if (alt_ioc_ready && MptResetHandlers[ii]) {
1884 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1885 ioc->name, ioc->alt_ioc->name, ii));
1886 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1890 /* FIXME? Examine results here? */
1896 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1898 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1899 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1900 * 929X, 1030 or 1035.
1901 * @ioc: Pointer to MPT adapter structure
1902 * @pdev: Pointer to (struct pci_dev) structure
1904 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1905 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1908 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1910 struct pci_dev *peer=NULL;
1911 unsigned int slot = PCI_SLOT(pdev->devfn);
1912 unsigned int func = PCI_FUNC(pdev->devfn);
1913 MPT_ADAPTER *ioc_srch;
1915 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1916 " searching for devfn match on %x or %x\n",
1917 ioc->name, pci_name(pdev), pdev->bus->number,
1918 pdev->devfn, func-1, func+1));
1920 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1922 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1927 list_for_each_entry(ioc_srch, &ioc_list, list) {
1928 struct pci_dev *_pcidev = ioc_srch->pcidev;
1929 if (_pcidev == peer) {
1930 /* Paranoia checks */
1931 if (ioc->alt_ioc != NULL) {
1932 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1933 ioc->name, ioc->alt_ioc->name);
1935 } else if (ioc_srch->alt_ioc != NULL) {
1936 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1937 ioc_srch->name, ioc_srch->alt_ioc->name);
1940 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1941 ioc->name, ioc_srch->name));
1942 ioc_srch->alt_ioc = ioc;
1943 ioc->alt_ioc = ioc_srch;
1949 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1951 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1952 * @this: Pointer to MPT adapter structure
1955 mpt_adapter_disable(MPT_ADAPTER *ioc)
1960 if (ioc->cached_fw != NULL) {
1961 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1962 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1963 printk(KERN_WARNING MYNAM
1964 ": firmware downloadboot failure (%d)!\n", ret);
1968 /* Disable adapter interrupts! */
1969 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1971 /* Clear any lingering interrupt */
1972 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1974 if (ioc->alloc != NULL) {
1976 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1977 ioc->name, ioc->alloc, ioc->alloc_sz));
1978 pci_free_consistent(ioc->pcidev, sz,
1979 ioc->alloc, ioc->alloc_dma);
1980 ioc->reply_frames = NULL;
1981 ioc->req_frames = NULL;
1983 ioc->alloc_total -= sz;
1986 if (ioc->sense_buf_pool != NULL) {
1987 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1988 pci_free_consistent(ioc->pcidev, sz,
1989 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1990 ioc->sense_buf_pool = NULL;
1991 ioc->alloc_total -= sz;
1994 if (ioc->events != NULL){
1995 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1998 ioc->alloc_total -= sz;
2001 if (ioc->cached_fw != NULL) {
2002 sz = ioc->facts.FWImageSize;
2003 pci_free_consistent(ioc->pcidev, sz,
2004 ioc->cached_fw, ioc->cached_fw_dma);
2005 ioc->cached_fw = NULL;
2006 ioc->alloc_total -= sz;
2009 kfree(ioc->spi_data.nvram);
2010 kfree(ioc->raid_data.pIocPg3);
2011 ioc->spi_data.nvram = NULL;
2012 ioc->raid_data.pIocPg3 = NULL;
2014 if (ioc->spi_data.pIocPg4 != NULL) {
2015 sz = ioc->spi_data.IocPg4Sz;
2016 pci_free_consistent(ioc->pcidev, sz,
2017 ioc->spi_data.pIocPg4,
2018 ioc->spi_data.IocPg4_dma);
2019 ioc->spi_data.pIocPg4 = NULL;
2020 ioc->alloc_total -= sz;
2023 if (ioc->ReqToChain != NULL) {
2024 kfree(ioc->ReqToChain);
2025 kfree(ioc->RequestNB);
2026 ioc->ReqToChain = NULL;
2029 kfree(ioc->ChainToChain);
2030 ioc->ChainToChain = NULL;
2032 if (ioc->HostPageBuffer != NULL) {
2033 if((ret = mpt_host_page_access_control(ioc,
2034 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2035 printk(KERN_ERR MYNAM
2036 ": %s: host page buffers free failed (%d)!\n",
2039 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2040 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2041 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2042 ioc->HostPageBuffer,
2043 ioc->HostPageBuffer_dma);
2044 ioc->HostPageBuffer = NULL;
2045 ioc->HostPageBuffer_sz = 0;
2046 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2052 * mpt_adapter_dispose - Free all resources associated with a MPT
2054 * @ioc: Pointer to MPT adapter structure
2056 * This routine unregisters h/w resources and frees all alloc'd memory
2057 * associated with a MPT adapter structure.
2060 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2062 int sz_first, sz_last;
2067 sz_first = ioc->alloc_total;
2069 mpt_adapter_disable(ioc);
2071 if (ioc->pci_irq != -1) {
2072 free_irq(ioc->pci_irq, ioc);
2076 if (ioc->memmap != NULL) {
2077 iounmap(ioc->memmap);
2081 #if defined(CONFIG_MTRR) && 0
2082 if (ioc->mtrr_reg > 0) {
2083 mtrr_del(ioc->mtrr_reg, 0, 0);
2084 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2088 /* Zap the adapter lookup ptr! */
2089 list_del(&ioc->list);
2091 sz_last = ioc->alloc_total;
2092 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2093 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2097 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2099 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2100 * @ioc: Pointer to MPT adapter structure
2103 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2107 printk(KERN_INFO "%s: ", ioc->name);
2108 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2109 printk("%s: ", ioc->prod_name+3);
2110 printk("Capabilities={");
2112 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2113 printk("Initiator");
2117 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2118 printk("%sTarget", i ? "," : "");
2122 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2123 printk("%sLAN", i ? "," : "");
2129 * This would probably evoke more questions than it's worth
2131 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2132 printk("%sLogBusAddr", i ? "," : "");
2140 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2142 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2143 * @ioc: Pointer to MPT_ADAPTER structure
2144 * @force: Force hard KickStart of IOC
2145 * @sleepFlag: Specifies whether the process can sleep
2148 * 1 - DIAG reset and READY
2149 * 0 - READY initially OR soft reset and READY
2150 * -1 - Any failure on KickStart
2151 * -2 - Msg Unit Reset Failed
2152 * -3 - IO Unit Reset Failed
2153 * -4 - IOC owned by a PEER
2156 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2161 int hard_reset_done = 0;
2166 /* Get current [raw] IOC state */
2167 ioc_state = mpt_GetIocState(ioc, 0);
2168 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2171 * Check to see if IOC got left/stuck in doorbell handshake
2172 * grip of death. If so, hard reset the IOC.
2174 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2176 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2180 /* Is it already READY? */
2181 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2185 * Check to see if IOC is in FAULT state.
2187 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2189 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2191 printk(KERN_WARNING " FAULT code = %04xh\n",
2192 ioc_state & MPI_DOORBELL_DATA_MASK);
2196 * Hmmm... Did it get left operational?
2198 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2199 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2203 * If PCI Peer, exit.
2204 * Else, if no fault conditions are present, issue a MessageUnitReset
2205 * Else, fall through to KickStart case
2207 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2208 dinitprintk((KERN_INFO MYNAM
2209 ": whoinit 0x%x statefault %d force %d\n",
2210 whoinit, statefault, force));
2211 if (whoinit == MPI_WHOINIT_PCI_PEER)
2214 if ((statefault == 0 ) && (force == 0)) {
2215 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2222 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2223 if (hard_reset_done < 0)
2227 * Loop here waiting for IOC to come READY.
2230 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2232 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2233 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2235 * BIOS or previous driver load left IOC in OP state.
2236 * Reset messaging FIFOs.
2238 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2239 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2242 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2244 * Something is wrong. Try to get IOC back
2247 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2248 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2255 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2256 ioc->name, (int)((ii+5)/HZ));
2260 if (sleepFlag == CAN_SLEEP) {
2261 msleep_interruptible(1);
2263 mdelay (1); /* 1 msec delay */
2268 if (statefault < 3) {
2269 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2271 statefault==1 ? "stuck handshake" : "IOC FAULT");
2274 return hard_reset_done;
2277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2279 * mpt_GetIocState - Get the current state of a MPT adapter.
2280 * @ioc: Pointer to MPT_ADAPTER structure
2281 * @cooked: Request raw or cooked IOC state
2283 * Returns all IOC Doorbell register bits if cooked==0, else just the
2284 * Doorbell bits in MPI_IOC_STATE_MASK.
2287 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2292 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2293 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2294 sc = s & MPI_IOC_STATE_MASK;
2297 ioc->last_state = sc;
2299 return cooked ? sc : s;
2302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2304 * GetIocFacts - Send IOCFacts request to MPT adapter.
2305 * @ioc: Pointer to MPT_ADAPTER structure
2306 * @sleepFlag: Specifies whether the process can sleep
2307 * @reason: If recovery, only update facts.
2309 * Returns 0 for success, non-zero for failure.
2312 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2314 IOCFacts_t get_facts;
2315 IOCFactsReply_t *facts;
2323 /* IOC *must* NOT be in RESET state! */
2324 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2325 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2331 facts = &ioc->facts;
2333 /* Destination (reply area)... */
2334 reply_sz = sizeof(*facts);
2335 memset(facts, 0, reply_sz);
2337 /* Request area (get_facts on the stack right now!) */
2338 req_sz = sizeof(get_facts);
2339 memset(&get_facts, 0, req_sz);
2341 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2342 /* Assert: All other get_facts fields are zero! */
2344 dinitprintk((MYIOC_s_INFO_FMT
2345 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2346 ioc->name, req_sz, reply_sz));
2348 /* No non-zero fields in the get_facts request are greater than
2349 * 1 byte in size, so we can just fire it off as is.
2351 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2352 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2357 * Now byte swap (GRRR) the necessary fields before any further
2358 * inspection of reply contents.
2360 * But need to do some sanity checks on MsgLength (byte) field
2361 * to make sure we don't zero IOC's req_sz!
2363 /* Did we get a valid reply? */
2364 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2365 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2367 * If not been here, done that, save off first WhoInit value
2369 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2370 ioc->FirstWhoInit = facts->WhoInit;
2373 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2374 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2375 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2376 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2377 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2378 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2379 /* CHECKME! IOCStatus, IOCLogInfo */
2381 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2382 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2385 * FC f/w version changed between 1.1 and 1.2
2386 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2387 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2389 if (facts->MsgVersion < 0x0102) {
2391 * Handle old FC f/w style, convert to new...
2393 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2394 facts->FWVersion.Word =
2395 ((oldv<<12) & 0xFF000000) |
2396 ((oldv<<8) & 0x000FFF00);
2398 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2400 facts->ProductID = le16_to_cpu(facts->ProductID);
2401 facts->CurrentHostMfaHighAddr =
2402 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2403 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2404 facts->CurrentSenseBufferHighAddr =
2405 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2406 facts->CurReplyFrameSize =
2407 le16_to_cpu(facts->CurReplyFrameSize);
2408 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2411 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2412 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2413 * to 14 in MPI-1.01.0x.
2415 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2416 facts->MsgVersion > 0x0100) {
2417 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2420 sz = facts->FWImageSize;
2425 facts->FWImageSize = sz;
2427 if (!facts->RequestFrameSize) {
2428 /* Something is wrong! */
2429 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2434 r = sz = facts->BlockSize;
2435 vv = ((63 / (sz * 4)) + 1) & 0x03;
2436 ioc->NB_for_64_byte_frame = vv;
2442 ioc->NBShiftFactor = shiftFactor;
2443 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2444 ioc->name, vv, shiftFactor, r));
2446 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2448 * Set values for this IOC's request & reply frame sizes,
2449 * and request & reply queue depths...
2451 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2452 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2453 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2454 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2456 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2457 ioc->name, ioc->reply_sz, ioc->reply_depth));
2458 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2459 ioc->name, ioc->req_sz, ioc->req_depth));
2461 /* Get port facts! */
2462 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2466 printk(MYIOC_s_ERR_FMT
2467 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2468 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2469 RequestFrameSize)/sizeof(u32)));
2476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2478 * GetPortFacts - Send PortFacts request to MPT adapter.
2479 * @ioc: Pointer to MPT_ADAPTER structure
2480 * @portnum: Port number
2481 * @sleepFlag: Specifies whether the process can sleep
2483 * Returns 0 for success, non-zero for failure.
2486 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2488 PortFacts_t get_pfacts;
2489 PortFactsReply_t *pfacts;
2494 /* IOC *must* NOT be in RESET state! */
2495 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2496 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2502 pfacts = &ioc->pfacts[portnum];
2504 /* Destination (reply area)... */
2505 reply_sz = sizeof(*pfacts);
2506 memset(pfacts, 0, reply_sz);
2508 /* Request area (get_pfacts on the stack right now!) */
2509 req_sz = sizeof(get_pfacts);
2510 memset(&get_pfacts, 0, req_sz);
2512 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2513 get_pfacts.PortNumber = portnum;
2514 /* Assert: All other get_pfacts fields are zero! */
2516 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2517 ioc->name, portnum));
2519 /* No non-zero fields in the get_pfacts request are greater than
2520 * 1 byte in size, so we can just fire it off as is.
2522 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2523 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2527 /* Did we get a valid reply? */
2529 /* Now byte swap the necessary fields in the response. */
2530 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2531 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2532 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2533 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2534 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2535 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2536 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2537 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2538 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2545 * SendIocInit - Send IOCInit request to MPT adapter.
2546 * @ioc: Pointer to MPT_ADAPTER structure
2547 * @sleepFlag: Specifies whether the process can sleep
2549 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2551 * Returns 0 for success, non-zero for failure.
2554 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2557 MPIDefaultReply_t init_reply;
2563 memset(&ioc_init, 0, sizeof(ioc_init));
2564 memset(&init_reply, 0, sizeof(init_reply));
2566 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2567 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2569 /* If we are in a recovery mode and we uploaded the FW image,
2570 * then this pointer is not NULL. Skip the upload a second time.
2571 * Set this flag if cached_fw set for either IOC.
2573 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2577 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2578 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2580 if(ioc->bus_type == SAS)
2581 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2582 else if(ioc->bus_type == FC)
2583 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2585 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2586 ioc_init.MaxBuses = MPT_MAX_BUS;
2587 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2588 ioc->name, ioc->facts.MsgVersion));
2589 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2590 // set MsgVersion and HeaderVersion host driver was built with
2591 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2592 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2594 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2595 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2596 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2599 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2601 if (sizeof(dma_addr_t) == sizeof(u64)) {
2602 /* Save the upper 32-bits of the request
2603 * (reply) and sense buffers.
2605 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2606 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2608 /* Force 32-bit addressing */
2609 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2610 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2613 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2614 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2615 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2616 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2618 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2619 ioc->name, &ioc_init));
2621 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2622 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2624 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2628 /* No need to byte swap the multibyte fields in the reply
2629 * since we don't even look at it's contents.
2632 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2633 ioc->name, &ioc_init));
2635 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2636 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2640 /* YIKES! SUPER IMPORTANT!!!
2641 * Poll IocState until _OPERATIONAL while IOC is doing
2642 * LoopInit and TargetDiscovery!
2645 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2646 state = mpt_GetIocState(ioc, 1);
2647 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2648 if (sleepFlag == CAN_SLEEP) {
2649 msleep_interruptible(1);
2655 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2656 ioc->name, (int)((count+5)/HZ));
2660 state = mpt_GetIocState(ioc, 1);
2663 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2671 * SendPortEnable - Send PortEnable request to MPT adapter port.
2672 * @ioc: Pointer to MPT_ADAPTER structure
2673 * @portnum: Port number to enable
2674 * @sleepFlag: Specifies whether the process can sleep
2676 * Send PortEnable to bring IOC to OPERATIONAL state.
2678 * Returns 0 for success, non-zero for failure.
2681 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2683 PortEnable_t port_enable;
2684 MPIDefaultReply_t reply_buf;
2689 /* Destination... */
2690 reply_sz = sizeof(MPIDefaultReply_t);
2691 memset(&reply_buf, 0, reply_sz);
2693 req_sz = sizeof(PortEnable_t);
2694 memset(&port_enable, 0, req_sz);
2696 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2697 port_enable.PortNumber = portnum;
2698 /* port_enable.ChainOffset = 0; */
2699 /* port_enable.MsgFlags = 0; */
2700 /* port_enable.MsgContext = 0; */
2702 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2703 ioc->name, portnum, &port_enable));
2705 /* RAID FW may take a long time to enable
2707 if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2708 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
2709 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2710 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2712 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2713 reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
2719 * ioc: Pointer to MPT_ADAPTER structure
2720 * size - total FW bytes
2723 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2726 return; /* use already allocated memory */
2727 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2728 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2729 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2731 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2732 ioc->alloc_total += size;
2736 * If alt_img is NULL, delete from ioc structure.
2737 * Else, delete a secondary image in same format.
2740 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2744 sz = ioc->facts.FWImageSize;
2745 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2746 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2747 pci_free_consistent(ioc->pcidev, sz,
2748 ioc->cached_fw, ioc->cached_fw_dma);
2749 ioc->cached_fw = NULL;
2755 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2757 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2758 * @ioc: Pointer to MPT_ADAPTER structure
2759 * @sleepFlag: Specifies whether the process can sleep
2761 * Returns 0 for success, >0 for handshake failure
2762 * <0 for fw upload failure.
2764 * Remark: If bound IOC and a successful FWUpload was performed
2765 * on the bound IOC, the second image is discarded
2766 * and memory is free'd. Both channels must upload to prevent
2767 * IOC from running in degraded mode.
2770 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2772 u8 request[ioc->req_sz];
2773 u8 reply[sizeof(FWUploadReply_t)];
2774 FWUpload_t *prequest;
2775 FWUploadReply_t *preply;
2776 FWUploadTCSGE_t *ptcsge;
2779 int ii, sz, reply_sz;
2782 /* If the image size is 0, we are done.
2784 if ((sz = ioc->facts.FWImageSize) == 0)
2787 mpt_alloc_fw_memory(ioc, sz);
2789 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2790 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2792 if (ioc->cached_fw == NULL) {
2798 prequest = (FWUpload_t *)&request;
2799 preply = (FWUploadReply_t *)&reply;
2801 /* Destination... */
2802 memset(prequest, 0, ioc->req_sz);
2804 reply_sz = sizeof(reply);
2805 memset(preply, 0, reply_sz);
2807 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2808 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2810 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2811 ptcsge->DetailsLength = 12;
2812 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2813 ptcsge->ImageSize = cpu_to_le32(sz);
2815 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2817 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2818 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2820 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2821 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2822 prequest, sgeoffset));
2823 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2825 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2826 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2828 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2830 cmdStatus = -EFAULT;
2832 /* Handshake transfer was complete and successful.
2833 * Check the Reply Frame.
2835 int status, transfer_sz;
2836 status = le16_to_cpu(preply->IOCStatus);
2837 if (status == MPI_IOCSTATUS_SUCCESS) {
2838 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2839 if (transfer_sz == sz)
2843 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2844 ioc->name, cmdStatus));
2849 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2851 mpt_free_fw_memory(ioc);
2857 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2859 * mpt_downloadboot - DownloadBoot code
2860 * @ioc: Pointer to MPT_ADAPTER structure
2861 * @flag: Specify which part of IOC memory is to be uploaded.
2862 * @sleepFlag: Specifies whether the process can sleep
2864 * FwDownloadBoot requires Programmed IO access.
2866 * Returns 0 for success
2867 * -1 FW Image size is 0
2868 * -2 No valid cached_fw Pointer
2869 * <0 for fw upload failure.
2872 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2874 MpiExtImageHeader_t *pExtImage;
2884 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2885 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2887 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2888 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2889 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2890 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2891 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2892 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2894 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2897 if (sleepFlag == CAN_SLEEP) {
2898 msleep_interruptible(1);
2903 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2904 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2906 for (count = 0; count < 30; count ++) {
2907 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2908 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2909 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2914 if (sleepFlag == CAN_SLEEP) {
2915 msleep_interruptible (100);
2921 if ( count == 30 ) {
2922 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2923 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2924 ioc->name, diag0val));
2928 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2929 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2930 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2931 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2932 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2933 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2935 /* Set the DiagRwEn and Disable ARM bits */
2936 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2938 fwSize = (pFwHeader->ImageSize + 3)/4;
2939 ptrFw = (u32 *) pFwHeader;
2941 /* Write the LoadStartAddress to the DiagRw Address Register
2942 * using Programmed IO
2944 if (ioc->errata_flag_1064)
2945 pci_enable_io_access(ioc->pcidev);
2947 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2948 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2949 ioc->name, pFwHeader->LoadStartAddress));
2951 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2952 ioc->name, fwSize*4, ptrFw));
2954 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2957 nextImage = pFwHeader->NextImageHeaderOffset;
2959 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2961 load_addr = pExtImage->LoadStartAddress;
2963 fwSize = (pExtImage->ImageSize + 3) >> 2;
2964 ptrFw = (u32 *)pExtImage;
2966 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
2967 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
2968 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2971 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2973 nextImage = pExtImage->NextImageHeaderOffset;
2976 /* Write the IopResetVectorRegAddr */
2977 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2978 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2980 /* Write the IopResetVectorValue */
2981 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2982 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2984 /* Clear the internal flash bad bit - autoincrementing register,
2985 * so must do two writes.
2987 if (ioc->bus_type == SCSI) {
2989 * 1030 and 1035 H/W errata, workaround to access
2990 * the ClearFlashBadSignatureBit
2992 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2993 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2994 diagRwData |= 0x40000000;
2995 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2996 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2998 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
2999 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3000 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3001 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3004 if (sleepFlag == CAN_SLEEP) {
3005 msleep_interruptible (1);
3011 if (ioc->errata_flag_1064)
3012 pci_disable_io_access(ioc->pcidev);
3014 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3015 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3016 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3017 ioc->name, diag0val));
3018 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3019 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3020 ioc->name, diag0val));
3021 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3023 /* Write 0xFF to reset the sequencer */
3024 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3026 if (ioc->bus_type == SAS) {
3027 ioc_state = mpt_GetIocState(ioc, 0);
3028 if ( (GetIocFacts(ioc, sleepFlag,
3029 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3030 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3031 ioc->name, ioc_state));
3036 for (count=0; count<HZ*20; count++) {
3037 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3038 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3039 ioc->name, count, ioc_state));
3040 if (ioc->bus_type == SAS) {
3043 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3044 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3048 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3052 if (sleepFlag == CAN_SLEEP) {
3053 msleep_interruptible (10);
3058 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3059 ioc->name, ioc_state));
3063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3065 * KickStart - Perform hard reset of MPT adapter.
3066 * @ioc: Pointer to MPT_ADAPTER structure
3067 * @force: Force hard reset
3068 * @sleepFlag: Specifies whether the process can sleep
3070 * This routine places MPT adapter in diagnostic mode via the
3071 * WriteSequence register, and then performs a hard reset of adapter
3072 * via the Diagnostic register.
3074 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3075 * or NO_SLEEP (interrupt thread, use mdelay)
3076 * force - 1 if doorbell active, board fault state
3077 * board operational, IOC_RECOVERY or
3078 * IOC_BRINGUP and there is an alt_ioc.
3082 * 1 - hard reset, READY
3083 * 0 - no reset due to History bit, READY
3084 * -1 - no reset due to History bit but not READY
3085 * OR reset but failed to come READY
3086 * -2 - no reset, could not enter DIAG mode
3087 * -3 - reset but bad FW bit
3090 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3092 int hard_reset_done = 0;
3096 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3097 if (ioc->bus_type == SCSI) {
3098 /* Always issue a Msg Unit Reset first. This will clear some
3099 * SCSI bus hang conditions.
3101 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3103 if (sleepFlag == CAN_SLEEP) {
3104 msleep_interruptible (1000);
3110 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3111 if (hard_reset_done < 0)
3112 return hard_reset_done;
3114 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3117 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3118 for (cnt=0; cnt<cntdn; cnt++) {
3119 ioc_state = mpt_GetIocState(ioc, 1);
3120 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3121 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3123 return hard_reset_done;
3125 if (sleepFlag == CAN_SLEEP) {
3126 msleep_interruptible (10);
3132 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3133 ioc->name, ioc_state);
3137 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3139 * mpt_diag_reset - Perform hard reset of the adapter.
3140 * @ioc: Pointer to MPT_ADAPTER structure
3141 * @ignore: Set if to honor and clear to ignore
3142 * the reset history bit
3143 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3144 * else set to NO_SLEEP (use mdelay instead)
3146 * This routine places the adapter in diagnostic mode via the
3147 * WriteSequence register and then performs a hard reset of adapter
3148 * via the Diagnostic register. Adapter should be in ready state
3149 * upon successful completion.
3151 * Returns: 1 hard reset successful
3152 * 0 no reset performed because reset history bit set
3153 * -2 enabling diagnostic mode failed
3154 * -3 diagnostic reset failed
3157 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3161 int hard_reset_done = 0;
3167 /* Clear any existing interrupts */
3168 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3170 /* Use "Diagnostic reset" method! (only thing available!) */
3171 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3175 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3176 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3177 ioc->name, diag0val, diag1val));
3180 /* Do the reset if we are told to ignore the reset history
3181 * or if the reset history is 0
3183 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3184 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3185 /* Write magic sequence to WriteSequence register
3186 * Loop until in diagnostic mode
3188 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3189 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3190 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3191 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3192 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3193 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3196 if (sleepFlag == CAN_SLEEP) {
3197 msleep_interruptible (100);
3204 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3205 ioc->name, diag0val);
3210 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3212 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3213 ioc->name, diag0val));
3218 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3219 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3220 ioc->name, diag0val, diag1val));
3223 * Disable the ARM (Bug fix)
3226 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3230 * Now hit the reset bit in the Diagnostic register
3231 * (THE BIG HAMMER!) (Clears DRWE bit).
3233 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3234 hard_reset_done = 1;
3235 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3239 * Call each currently registered protocol IOC reset handler
3240 * with pre-reset indication.
3241 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3242 * MptResetHandlers[] registered yet.
3248 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3249 if (MptResetHandlers[ii]) {
3250 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3252 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3254 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3255 ioc->name, ioc->alt_ioc->name, ii));
3256 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3260 /* FIXME? Examine results here? */
3263 if (ioc->cached_fw) {
3264 /* If the DownloadBoot operation fails, the
3265 * IOC will be left unusable. This is a fatal error
3266 * case. _diag_reset will return < 0
3268 for (count = 0; count < 30; count ++) {
3269 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3270 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3275 if (sleepFlag == CAN_SLEEP) {
3276 msleep_interruptible (1000);
3281 if ((count = mpt_downloadboot(ioc,
3282 (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
3283 printk(KERN_WARNING MYNAM
3284 ": firmware downloadboot failure (%d)!\n", count);
3288 /* Wait for FW to reload and for board
3289 * to go to the READY state.
3290 * Maximum wait is 60 seconds.
3291 * If fail, no error will check again
3292 * with calling program.
3294 for (count = 0; count < 60; count ++) {
3295 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3296 doorbell &= MPI_IOC_STATE_MASK;
3298 if (doorbell == MPI_IOC_STATE_READY) {
3303 if (sleepFlag == CAN_SLEEP) {
3304 msleep_interruptible (1000);
3312 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3315 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3316 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3317 ioc->name, diag0val, diag1val));
3320 /* Clear RESET_HISTORY bit! Place board in the
3321 * diagnostic mode to update the diag register.
3323 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3325 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3326 /* Write magic sequence to WriteSequence register
3327 * Loop until in diagnostic mode
3329 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3330 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3331 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3332 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3333 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3334 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3337 if (sleepFlag == CAN_SLEEP) {
3338 msleep_interruptible (100);
3345 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3346 ioc->name, diag0val);
3349 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3351 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3352 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3353 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3354 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3355 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3359 /* Disable Diagnostic Mode
3361 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3363 /* Check FW reload status flags.
3365 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3366 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3367 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3368 ioc->name, diag0val);
3374 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3375 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3376 ioc->name, diag0val, diag1val));
3380 * Reset flag that says we've enabled event notification
3382 ioc->facts.EventState = 0;
3385 ioc->alt_ioc->facts.EventState = 0;
3387 return hard_reset_done;
3390 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3392 * SendIocReset - Send IOCReset request to MPT adapter.
3393 * @ioc: Pointer to MPT_ADAPTER structure
3394 * @reset_type: reset type, expected values are
3395 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3397 * Send IOCReset request to the MPT adapter.
3399 * Returns 0 for success, non-zero for failure.
3402 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3408 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3409 ioc->name, reset_type));
3410 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3411 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3414 /* FW ACK'd request, wait for READY state
3417 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3419 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3423 if (sleepFlag != CAN_SLEEP)
3426 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3427 ioc->name, (int)((count+5)/HZ));
3431 if (sleepFlag == CAN_SLEEP) {
3432 msleep_interruptible(1);
3434 mdelay (1); /* 1 msec delay */
3439 * Cleanup all event stuff for this IOC; re-issue EventNotification
3440 * request if needed.
3442 if (ioc->facts.Function)
3443 ioc->facts.EventState = 0;
3448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3450 * initChainBuffers - Allocate memory for and initialize
3451 * chain buffers, chain buffer control arrays and spinlock.
3452 * @hd: Pointer to MPT_SCSI_HOST structure
3453 * @init: If set, initialize the spin lock.
3456 initChainBuffers(MPT_ADAPTER *ioc)
3459 int sz, ii, num_chain;
3460 int scale, num_sge, numSGE;
3462 /* ReqToChain size must equal the req_depth
3465 if (ioc->ReqToChain == NULL) {
3466 sz = ioc->req_depth * sizeof(int);
3467 mem = kmalloc(sz, GFP_ATOMIC);
3471 ioc->ReqToChain = (int *) mem;
3472 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3473 ioc->name, mem, sz));
3474 mem = kmalloc(sz, GFP_ATOMIC);
3478 ioc->RequestNB = (int *) mem;
3479 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3480 ioc->name, mem, sz));
3482 for (ii = 0; ii < ioc->req_depth; ii++) {
3483 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3486 /* ChainToChain size must equal the total number
3487 * of chain buffers to be allocated.
3490 * Calculate the number of chain buffers needed(plus 1) per I/O
3491 * then multiply the the maximum number of simultaneous cmds
3493 * num_sge = num sge in request frame + last chain buffer
3494 * scale = num sge per chain buffer if no chain element
3496 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3497 if (sizeof(dma_addr_t) == sizeof(u64))
3498 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3500 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3502 if (sizeof(dma_addr_t) == sizeof(u64)) {
3503 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3504 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3506 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3507 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3509 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3510 ioc->name, num_sge, numSGE));
3512 if ( numSGE > MPT_SCSI_SG_DEPTH )
3513 numSGE = MPT_SCSI_SG_DEPTH;
3516 while (numSGE - num_sge > 0) {
3518 num_sge += (scale - 1);
3522 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3523 ioc->name, numSGE, num_sge, num_chain));
3525 if (ioc->bus_type == SCSI)
3526 num_chain *= MPT_SCSI_CAN_QUEUE;
3528 num_chain *= MPT_FC_CAN_QUEUE;
3530 ioc->num_chain = num_chain;
3532 sz = num_chain * sizeof(int);
3533 if (ioc->ChainToChain == NULL) {
3534 mem = kmalloc(sz, GFP_ATOMIC);
3538 ioc->ChainToChain = (int *) mem;
3539 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3540 ioc->name, mem, sz));
3542 mem = (u8 *) ioc->ChainToChain;
3544 memset(mem, 0xFF, sz);
3548 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3550 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3551 * @ioc: Pointer to MPT_ADAPTER structure
3553 * This routine allocates memory for the MPT reply and request frame
3554 * pools (if necessary), and primes the IOC reply FIFO with
3557 * Returns 0 for success, non-zero for failure.
3560 PrimeIocFifos(MPT_ADAPTER *ioc)
3563 unsigned long flags;
3564 dma_addr_t alloc_dma;
3566 int i, reply_sz, sz, total_size, num_chain;
3568 /* Prime reply FIFO... */
3570 if (ioc->reply_frames == NULL) {
3571 if ( (num_chain = initChainBuffers(ioc)) < 0)
3574 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3575 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3576 ioc->name, ioc->reply_sz, ioc->reply_depth));
3577 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3578 ioc->name, reply_sz, reply_sz));
3580 sz = (ioc->req_sz * ioc->req_depth);
3581 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3582 ioc->name, ioc->req_sz, ioc->req_depth));
3583 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3584 ioc->name, sz, sz));
3587 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3588 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3589 ioc->name, ioc->req_sz, num_chain));
3590 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3591 ioc->name, sz, sz, num_chain));
3594 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3596 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3601 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3602 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3604 memset(mem, 0, total_size);
3605 ioc->alloc_total += total_size;
3607 ioc->alloc_dma = alloc_dma;
3608 ioc->alloc_sz = total_size;
3609 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3610 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3612 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3613 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3615 alloc_dma += reply_sz;
3618 /* Request FIFO - WE manage this! */
3620 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3621 ioc->req_frames_dma = alloc_dma;
3623 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3624 ioc->name, mem, (void *)(ulong)alloc_dma));
3626 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3628 #if defined(CONFIG_MTRR) && 0
3630 * Enable Write Combining MTRR for IOC's memory region.
3631 * (at least as much as we can; "size and base must be
3632 * multiples of 4 kiB"
3634 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3636 MTRR_TYPE_WRCOMB, 1);
3637 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3638 ioc->name, ioc->req_frames_dma, sz));
3641 for (i = 0; i < ioc->req_depth; i++) {
3642 alloc_dma += ioc->req_sz;
3646 ioc->ChainBuffer = mem;
3647 ioc->ChainBufferDMA = alloc_dma;
3649 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3650 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3652 /* Initialize the free chain Q.
3655 INIT_LIST_HEAD(&ioc->FreeChainQ);
3657 /* Post the chain buffers to the FreeChainQ.
3659 mem = (u8 *)ioc->ChainBuffer;
3660 for (i=0; i < num_chain; i++) {
3661 mf = (MPT_FRAME_HDR *) mem;
3662 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3666 /* Initialize Request frames linked list
3668 alloc_dma = ioc->req_frames_dma;
3669 mem = (u8 *) ioc->req_frames;
3671 spin_lock_irqsave(&ioc->FreeQlock, flags);
3672 INIT_LIST_HEAD(&ioc->FreeQ);
3673 for (i = 0; i < ioc->req_depth; i++) {
3674 mf = (MPT_FRAME_HDR *) mem;
3676 /* Queue REQUESTs *internally*! */
3677 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3681 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3683 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3684 ioc->sense_buf_pool =
3685 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3686 if (ioc->sense_buf_pool == NULL) {
3687 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3692 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3693 ioc->alloc_total += sz;
3694 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3695 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3699 /* Post Reply frames to FIFO
3701 alloc_dma = ioc->alloc_dma;
3702 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3703 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3705 for (i = 0; i < ioc->reply_depth; i++) {
3706 /* Write each address to the IOC! */
3707 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3708 alloc_dma += ioc->reply_sz;
3714 if (ioc->alloc != NULL) {
3716 pci_free_consistent(ioc->pcidev,
3718 ioc->alloc, ioc->alloc_dma);
3719 ioc->reply_frames = NULL;
3720 ioc->req_frames = NULL;
3721 ioc->alloc_total -= sz;
3723 if (ioc->sense_buf_pool != NULL) {
3724 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3725 pci_free_consistent(ioc->pcidev,
3727 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3728 ioc->sense_buf_pool = NULL;
3733 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3735 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3736 * from IOC via doorbell handshake method.
3737 * @ioc: Pointer to MPT_ADAPTER structure
3738 * @reqBytes: Size of the request in bytes
3739 * @req: Pointer to MPT request frame
3740 * @replyBytes: Expected size of the reply in bytes
3741 * @u16reply: Pointer to area where reply should be written
3742 * @maxwait: Max wait time for a reply (in seconds)
3743 * @sleepFlag: Specifies whether the process can sleep
3745 * NOTES: It is the callers responsibility to byte-swap fields in the
3746 * request which are greater than 1 byte in size. It is also the
3747 * callers responsibility to byte-swap response fields which are
3748 * greater than 1 byte in size.
3750 * Returns 0 for success, non-zero for failure.
3753 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3754 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3756 MPIDefaultReply_t *mptReply;
3761 * Get ready to cache a handshake reply
3763 ioc->hs_reply_idx = 0;
3764 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3765 mptReply->MsgLength = 0;
3768 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3769 * then tell IOC that we want to handshake a request of N words.
3770 * (WRITE u32val to Doorbell reg).
3772 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3773 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3774 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3775 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3778 * Wait for IOC's doorbell handshake int
3780 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3783 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3784 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3786 /* Read doorbell and check for active bit */
3787 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3791 * Clear doorbell int (WRITE 0 to IntStatus reg),
3792 * then wait for IOC to ACKnowledge that it's ready for
3793 * our handshake request.
3795 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3796 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3801 u8 *req_as_bytes = (u8 *) req;
3804 * Stuff request words via doorbell handshake,
3805 * with ACK from IOC for each.
3807 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3808 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3809 (req_as_bytes[(ii*4) + 1] << 8) |
3810 (req_as_bytes[(ii*4) + 2] << 16) |
3811 (req_as_bytes[(ii*4) + 3] << 24));
3813 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3814 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3818 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3819 DBG_DUMP_REQUEST_FRAME_HDR(req)
3821 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3822 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3825 * Wait for completion of doorbell handshake reply from the IOC
3827 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3830 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3831 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3834 * Copy out the cached reply...
3836 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3837 u16reply[ii] = ioc->hs_reply[ii];
3845 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3847 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3848 * in it's IntStatus register.
3849 * @ioc: Pointer to MPT_ADAPTER structure
3850 * @howlong: How long to wait (in seconds)
3851 * @sleepFlag: Specifies whether the process can sleep
3853 * This routine waits (up to ~2 seconds max) for IOC doorbell
3854 * handshake ACKnowledge.
3856 * Returns a negative value on failure, else wait loop count.
3859 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3865 cntdn = 1000 * howlong;
3867 if (sleepFlag == CAN_SLEEP) {
3869 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3870 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3872 msleep_interruptible (1);
3877 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3878 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3886 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3891 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3892 ioc->name, count, intstat);
3896 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3898 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3899 * in it's IntStatus register.
3900 * @ioc: Pointer to MPT_ADAPTER structure
3901 * @howlong: How long to wait (in seconds)
3902 * @sleepFlag: Specifies whether the process can sleep
3904 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3906 * Returns a negative value on failure, else wait loop count.
3909 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3915 cntdn = 1000 * howlong;
3916 if (sleepFlag == CAN_SLEEP) {
3918 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3919 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3921 msleep_interruptible(1);
3926 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3927 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3935 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3936 ioc->name, count, howlong));
3940 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3941 ioc->name, count, intstat);
3945 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3947 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3948 * @ioc: Pointer to MPT_ADAPTER structure
3949 * @howlong: How long to wait (in seconds)
3950 * @sleepFlag: Specifies whether the process can sleep
3952 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3953 * Reply is cached to IOC private area large enough to hold a maximum
3954 * of 128 bytes of reply data.
3956 * Returns a negative value on failure, else size of reply in WORDS.
3959 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3964 u16 *hs_reply = ioc->hs_reply;
3965 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3968 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3971 * Get first two u16's so we can look at IOC's intended reply MsgLength
3974 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3977 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3978 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3979 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3982 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3983 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3987 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3988 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3989 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3992 * If no error (and IOC said MsgLength is > 0), piece together
3993 * reply 16 bits at a time.
3995 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3996 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3998 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3999 /* don't overflow our IOC hs_reply[] buffer! */
4000 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4001 hs_reply[u16cnt] = hword;
4002 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4005 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4007 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4010 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4015 else if (u16cnt != (2 * mptReply->MsgLength)) {
4018 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4023 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4024 DBG_DUMP_REPLY_FRAME(mptReply)
4026 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4027 ioc->name, t, u16cnt/2));
4031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4033 * GetLanConfigPages - Fetch LANConfig pages.
4034 * @ioc: Pointer to MPT_ADAPTER structure
4036 * Return: 0 for success
4037 * -ENOMEM if no memory available
4038 * -EPERM if not allowed due to ISR context
4039 * -EAGAIN if no msg frames currently available
4040 * -EFAULT for non-successful reply or no reply (timeout)
4043 GetLanConfigPages(MPT_ADAPTER *ioc)
4045 ConfigPageHeader_t hdr;
4047 LANPage0_t *ppage0_alloc;
4048 dma_addr_t page0_dma;
4049 LANPage1_t *ppage1_alloc;
4050 dma_addr_t page1_dma;
4055 /* Get LAN Page 0 header */
4056 hdr.PageVersion = 0;
4059 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4060 cfg.cfghdr.hdr = &hdr;
4062 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4067 if ((rc = mpt_config(ioc, &cfg)) != 0)
4070 if (hdr.PageLength > 0) {
4071 data_sz = hdr.PageLength * 4;
4072 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4075 memset((u8 *)ppage0_alloc, 0, data_sz);
4076 cfg.physAddr = page0_dma;
4077 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4079 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4081 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4082 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4086 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4089 * Normalize endianness of structure data,
4090 * by byte-swapping all > 1 byte fields!
4099 /* Get LAN Page 1 header */
4100 hdr.PageVersion = 0;
4103 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4104 cfg.cfghdr.hdr = &hdr;
4106 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4110 if ((rc = mpt_config(ioc, &cfg)) != 0)
4113 if (hdr.PageLength == 0)
4116 data_sz = hdr.PageLength * 4;
4118 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4120 memset((u8 *)ppage1_alloc, 0, data_sz);
4121 cfg.physAddr = page1_dma;
4122 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4124 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4126 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4127 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4130 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4133 * Normalize endianness of structure data,
4134 * by byte-swapping all > 1 byte fields!
4142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4144 * GetFcPortPage0 - Fetch FCPort config Page0.
4145 * @ioc: Pointer to MPT_ADAPTER structure
4146 * @portnum: IOC Port number
4148 * Return: 0 for success
4149 * -ENOMEM if no memory available
4150 * -EPERM if not allowed due to ISR context
4151 * -EAGAIN if no msg frames currently available
4152 * -EFAULT for non-successful reply or no reply (timeout)
4155 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4157 ConfigPageHeader_t hdr;
4159 FCPortPage0_t *ppage0_alloc;
4160 FCPortPage0_t *pp0dest;
4161 dma_addr_t page0_dma;
4166 /* Get FCPort Page 0 header */
4167 hdr.PageVersion = 0;
4170 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4171 cfg.cfghdr.hdr = &hdr;
4173 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4175 cfg.pageAddr = portnum;
4178 if ((rc = mpt_config(ioc, &cfg)) != 0)
4181 if (hdr.PageLength == 0)
4184 data_sz = hdr.PageLength * 4;
4186 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4188 memset((u8 *)ppage0_alloc, 0, data_sz);
4189 cfg.physAddr = page0_dma;
4190 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4192 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4194 pp0dest = &ioc->fc_port_page0[portnum];
4195 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4196 memcpy(pp0dest, ppage0_alloc, copy_sz);
4199 * Normalize endianness of structure data,
4200 * by byte-swapping all > 1 byte fields!
4202 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4203 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4204 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4205 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4206 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4207 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4208 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4209 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4210 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4211 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4212 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4213 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4214 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4215 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4216 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4217 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4221 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4227 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4229 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4230 * @ioc: Pointer to MPT_ADAPTER structure
4231 * @sas_address: 64bit SAS Address for operation.
4232 * @target_id: specified target for operation
4233 * @bus: specified bus for operation
4234 * @persist_opcode: see below
4236 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4237 * devices not currently present.
4238 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4240 * NOTE: Don't use not this function during interrupt time.
4242 * Returns: 0 for success, non-zero error
4245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4247 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4249 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4250 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4251 MPT_FRAME_HDR *mf = NULL;
4252 MPIHeader_t *mpi_hdr;
4255 /* insure garbage is not sent to fw */
4256 switch(persist_opcode) {
4258 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4259 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4267 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4269 /* Get a MF for this command.
4271 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4272 printk("%s: no msg frames!\n",__FUNCTION__);
4276 mpi_hdr = (MPIHeader_t *) mf;
4277 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4278 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4279 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4280 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4281 sasIoUnitCntrReq->Operation = persist_opcode;
4283 init_timer(&ioc->persist_timer);
4284 ioc->persist_timer.data = (unsigned long) ioc;
4285 ioc->persist_timer.function = mpt_timer_expired;
4286 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4287 ioc->persist_wait_done=0;
4288 add_timer(&ioc->persist_timer);
4289 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4290 wait_event(mpt_waitq, ioc->persist_wait_done);
4292 sasIoUnitCntrReply =
4293 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4294 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4295 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4297 sasIoUnitCntrReply->IOCStatus,
4298 sasIoUnitCntrReply->IOCLogInfo);
4302 printk("%s: success\n",__FUNCTION__);
4306 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4308 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4309 * @ioc: Pointer to MPT_ADAPTER structure
4311 * Returns: 0 for success
4312 * -ENOMEM if no memory available
4313 * -EPERM if not allowed due to ISR context
4314 * -EAGAIN if no msg frames currently available
4315 * -EFAULT for non-successful reply or no reply (timeout)
4318 GetIoUnitPage2(MPT_ADAPTER *ioc)
4320 ConfigPageHeader_t hdr;
4322 IOUnitPage2_t *ppage_alloc;
4323 dma_addr_t page_dma;
4327 /* Get the page header */
4328 hdr.PageVersion = 0;
4331 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4332 cfg.cfghdr.hdr = &hdr;
4334 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4339 if ((rc = mpt_config(ioc, &cfg)) != 0)
4342 if (hdr.PageLength == 0)
4345 /* Read the config page */
4346 data_sz = hdr.PageLength * 4;
4348 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4350 memset((u8 *)ppage_alloc, 0, data_sz);
4351 cfg.physAddr = page_dma;
4352 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4354 /* If Good, save data */
4355 if ((rc = mpt_config(ioc, &cfg)) == 0)
4356 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4358 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4364 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4365 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4366 * @ioc: Pointer to a Adapter Strucutre
4367 * @portnum: IOC port number
4369 * Return: -EFAULT if read of config page header fails
4371 * If read of SCSI Port Page 0 fails,
4372 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4373 * Adapter settings: async, narrow
4375 * If read of SCSI Port Page 2 fails,
4376 * Adapter settings valid
4377 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4382 * CHECK - what type of locking mechanisms should be used????
4385 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4390 ConfigPageHeader_t header;
4396 if (!ioc->spi_data.nvram) {
4399 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4400 mem = kmalloc(sz, GFP_ATOMIC);
4404 ioc->spi_data.nvram = (int *) mem;
4406 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4407 ioc->name, ioc->spi_data.nvram, sz));
4410 /* Invalidate NVRAM information
4412 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4413 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4416 /* Read SPP0 header, allocate memory, then read page.
4418 header.PageVersion = 0;
4419 header.PageLength = 0;
4420 header.PageNumber = 0;
4421 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4422 cfg.cfghdr.hdr = &header;
4424 cfg.pageAddr = portnum;
4425 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4427 cfg.timeout = 0; /* use default */
4428 if (mpt_config(ioc, &cfg) != 0)
4431 if (header.PageLength > 0) {
4432 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4434 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4435 cfg.physAddr = buf_dma;
4436 if (mpt_config(ioc, &cfg) != 0) {
4437 ioc->spi_data.maxBusWidth = MPT_NARROW;
4438 ioc->spi_data.maxSyncOffset = 0;
4439 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4440 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4442 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4443 ioc->name, ioc->spi_data.minSyncFactor));
4445 /* Save the Port Page 0 data
4447 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4448 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4449 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4451 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4452 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4453 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4454 ioc->name, pPP0->Capabilities));
4456 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4457 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4459 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4460 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4461 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4462 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4463 ioc->name, ioc->spi_data.minSyncFactor));
4465 ioc->spi_data.maxSyncOffset = 0;
4466 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4469 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4471 /* Update the minSyncFactor based on bus type.
4473 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4474 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4476 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4477 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4478 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4479 ioc->name, ioc->spi_data.minSyncFactor));
4484 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4489 /* SCSI Port Page 2 - Read the header then the page.
4491 header.PageVersion = 0;
4492 header.PageLength = 0;
4493 header.PageNumber = 2;
4494 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4495 cfg.cfghdr.hdr = &header;
4497 cfg.pageAddr = portnum;
4498 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4500 if (mpt_config(ioc, &cfg) != 0)
4503 if (header.PageLength > 0) {
4504 /* Allocate memory and read SCSI Port Page 2
4506 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4508 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4509 cfg.physAddr = buf_dma;
4510 if (mpt_config(ioc, &cfg) != 0) {
4511 /* Nvram data is left with INVALID mark
4515 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4516 MpiDeviceInfo_t *pdevice = NULL;
4518 /* Save the Port Page 2 data
4519 * (reformat into a 32bit quantity)
4521 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4522 ioc->spi_data.PortFlags = data;
4523 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4524 pdevice = &pPP2->DeviceSettings[ii];
4525 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4526 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4527 ioc->spi_data.nvram[ii] = data;
4531 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4535 /* Update Adapter limits with those from NVRAM
4536 * Comment: Don't need to do this. Target performance
4537 * parameters will never exceed the adapters limits.
4543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4544 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4545 * @ioc: Pointer to a Adapter Strucutre
4546 * @portnum: IOC port number
4548 * Return: -EFAULT if read of config page header fails
4552 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4555 ConfigPageHeader_t header;
4557 /* Read the SCSI Device Page 1 header
4559 header.PageVersion = 0;
4560 header.PageLength = 0;
4561 header.PageNumber = 1;
4562 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4563 cfg.cfghdr.hdr = &header;
4565 cfg.pageAddr = portnum;
4566 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4569 if (mpt_config(ioc, &cfg) != 0)
4572 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4573 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4575 header.PageVersion = 0;
4576 header.PageLength = 0;
4577 header.PageNumber = 0;
4578 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4579 if (mpt_config(ioc, &cfg) != 0)
4582 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4583 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4585 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4586 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4588 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4589 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4595 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4596 * @ioc: Pointer to a Adapter Strucutre
4597 * @portnum: IOC port number
4601 * -EFAULT if read of config page header fails or data pointer not NULL
4602 * -ENOMEM if pci_alloc failed
4605 mpt_findImVolumes(MPT_ADAPTER *ioc)
4609 ConfigPageIoc2RaidVol_t *pIocRv;
4610 dma_addr_t ioc2_dma;
4612 ConfigPageHeader_t header;
4619 /* Read IOCP2 header then the page.
4621 header.PageVersion = 0;
4622 header.PageLength = 0;
4623 header.PageNumber = 2;
4624 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4625 cfg.cfghdr.hdr = &header;
4628 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4631 if (mpt_config(ioc, &cfg) != 0)
4634 if (header.PageLength == 0)
4637 iocpage2sz = header.PageLength * 4;
4638 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4642 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4643 cfg.physAddr = ioc2_dma;
4644 if (mpt_config(ioc, &cfg) != 0)
4647 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4648 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4650 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4655 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4657 /* Identify RAID Volume Id's */
4658 nVols = pIoc2->NumActiveVolumes;
4664 /* At least 1 RAID Volume
4666 pIocRv = pIoc2->RaidVolume;
4667 ioc->raid_data.isRaid = 0;
4668 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4669 vid = pIocRv->VolumeID;
4670 vbus = pIocRv->VolumeBus;
4671 vioc = pIocRv->VolumeIOC;
4676 ioc->raid_data.isRaid |= (1 << vid);
4678 /* Error! Always bus 0
4684 /* Identify Hidden Physical Disk Id's */
4685 nPhys = pIoc2->NumActivePhysDisks;
4687 /* No physical disks.
4690 mpt_read_ioc_pg_3(ioc);
4694 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4700 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4705 ConfigPageHeader_t header;
4706 dma_addr_t ioc3_dma;
4709 /* Free the old page
4711 kfree(ioc->raid_data.pIocPg3);
4712 ioc->raid_data.pIocPg3 = NULL;
4714 /* There is at least one physical disk.
4715 * Read and save IOC Page 3
4717 header.PageVersion = 0;
4718 header.PageLength = 0;
4719 header.PageNumber = 3;
4720 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4721 cfg.cfghdr.hdr = &header;
4724 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4727 if (mpt_config(ioc, &cfg) != 0)
4730 if (header.PageLength == 0)
4733 /* Read Header good, alloc memory
4735 iocpage3sz = header.PageLength * 4;
4736 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4740 /* Read the Page and save the data
4741 * into malloc'd memory.
4743 cfg.physAddr = ioc3_dma;
4744 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4745 if (mpt_config(ioc, &cfg) == 0) {
4746 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4748 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4749 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4753 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4759 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4763 ConfigPageHeader_t header;
4764 dma_addr_t ioc4_dma;
4767 /* Read and save IOC Page 4
4769 header.PageVersion = 0;
4770 header.PageLength = 0;
4771 header.PageNumber = 4;
4772 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4773 cfg.cfghdr.hdr = &header;
4776 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4779 if (mpt_config(ioc, &cfg) != 0)
4782 if (header.PageLength == 0)
4785 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4786 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4787 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4791 ioc4_dma = ioc->spi_data.IocPg4_dma;
4792 iocpage4sz = ioc->spi_data.IocPg4Sz;
4795 /* Read the Page into dma memory.
4797 cfg.physAddr = ioc4_dma;
4798 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4799 if (mpt_config(ioc, &cfg) == 0) {
4800 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4801 ioc->spi_data.IocPg4_dma = ioc4_dma;
4802 ioc->spi_data.IocPg4Sz = iocpage4sz;
4804 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4805 ioc->spi_data.pIocPg4 = NULL;
4810 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4814 ConfigPageHeader_t header;
4815 dma_addr_t ioc1_dma;
4819 /* Check the Coalescing Timeout in IOC Page 1
4821 header.PageVersion = 0;
4822 header.PageLength = 0;
4823 header.PageNumber = 1;
4824 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4825 cfg.cfghdr.hdr = &header;
4828 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4831 if (mpt_config(ioc, &cfg) != 0)
4834 if (header.PageLength == 0)
4837 /* Read Header good, alloc memory
4839 iocpage1sz = header.PageLength * 4;
4840 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4844 /* Read the Page and check coalescing timeout
4846 cfg.physAddr = ioc1_dma;
4847 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4848 if (mpt_config(ioc, &cfg) == 0) {
4850 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4851 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4852 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4854 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4857 if (tmp > MPT_COALESCING_TIMEOUT) {
4858 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4860 /* Write NVRAM and current
4863 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4864 if (mpt_config(ioc, &cfg) == 0) {
4865 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4866 ioc->name, MPT_COALESCING_TIMEOUT));
4868 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4869 if (mpt_config(ioc, &cfg) == 0) {
4870 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4871 ioc->name, MPT_COALESCING_TIMEOUT));
4873 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4878 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4884 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4888 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4893 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4895 * SendEventNotification - Send EventNotification (on or off) request
4897 * @ioc: Pointer to MPT_ADAPTER structure
4898 * @EvSwitch: Event switch flags
4901 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4903 EventNotification_t *evnp;
4905 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4907 devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4911 memset(evnp, 0, sizeof(*evnp));
4913 devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
4915 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4916 evnp->ChainOffset = 0;
4918 evnp->Switch = EvSwitch;
4920 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4927 * SendEventAck - Send EventAck request to MPT adapter.
4928 * @ioc: Pointer to MPT_ADAPTER structure
4929 * @evnp: Pointer to original EventNotification request
4932 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4936 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4937 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
4938 "request frame for Event=%x EventContext=%x EventData=%x!\n",
4939 ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
4940 le32_to_cpu(evnp->Data[0]));
4943 memset(pAck, 0, sizeof(*pAck));
4945 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4947 pAck->Function = MPI_FUNCTION_EVENT_ACK;
4948 pAck->ChainOffset = 0;
4950 pAck->Event = evnp->Event;
4951 pAck->EventContext = evnp->EventContext;
4953 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4960 * mpt_config - Generic function to issue config message
4961 * @ioc - Pointer to an adapter structure
4962 * @cfg - Pointer to a configuration structure. Struct contains
4963 * action, page address, direction, physical address
4964 * and pointer to a configuration page header
4965 * Page header is updated.
4967 * Returns 0 for success
4968 * -EPERM if not allowed due to ISR context
4969 * -EAGAIN if no msg frames currently available
4970 * -EFAULT for non-successful reply or no reply (timeout)
4973 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4976 ConfigExtendedPageHeader_t *pExtHdr = NULL;
4978 unsigned long flags;
4983 /* Prevent calling wait_event() (below), if caller happens
4984 * to be in ISR context, because that is fatal!
4986 in_isr = in_interrupt();
4988 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4993 /* Get and Populate a free Frame
4995 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4996 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5000 pReq = (Config_t *)mf;
5001 pReq->Action = pCfg->action;
5003 pReq->ChainOffset = 0;
5004 pReq->Function = MPI_FUNCTION_CONFIG;
5006 /* Assume page type is not extended and clear "reserved" fields. */
5007 pReq->ExtPageLength = 0;
5008 pReq->ExtPageType = 0;
5011 for (ii=0; ii < 8; ii++)
5012 pReq->Reserved2[ii] = 0;
5014 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5015 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5016 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5017 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5019 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5020 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5021 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5022 pReq->ExtPageType = pExtHdr->ExtPageType;
5023 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5025 /* Page Length must be treated as a reserved field for the extended header. */
5026 pReq->Header.PageLength = 0;
5029 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5031 /* Add a SGE to the config request.
5034 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5036 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5038 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5039 flagsLength |= pExtHdr->ExtPageLength * 4;
5041 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5042 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5045 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5047 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5048 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5051 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5053 /* Append pCfg pointer to end of mf
5055 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5057 /* Initalize the timer
5059 init_timer(&pCfg->timer);
5060 pCfg->timer.data = (unsigned long) ioc;
5061 pCfg->timer.function = mpt_timer_expired;
5062 pCfg->wait_done = 0;
5064 /* Set the timer; ensure 10 second minimum */
5065 if (pCfg->timeout < 10)
5066 pCfg->timer.expires = jiffies + HZ*10;
5068 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5070 /* Add to end of Q, set timer and then issue this command */
5071 spin_lock_irqsave(&ioc->FreeQlock, flags);
5072 list_add_tail(&pCfg->linkage, &ioc->configQ);
5073 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5075 add_timer(&pCfg->timer);
5076 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5077 wait_event(mpt_waitq, pCfg->wait_done);
5079 /* mf has been freed - do not access */
5086 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5088 * mpt_toolbox - Generic function to issue toolbox message
5089 * @ioc - Pointer to an adapter structure
5090 * @cfg - Pointer to a toolbox structure. Struct contains
5091 * action, page address, direction, physical address
5092 * and pointer to a configuration page header
5093 * Page header is updated.
5095 * Returns 0 for success
5096 * -EPERM if not allowed due to ISR context
5097 * -EAGAIN if no msg frames currently available
5098 * -EFAULT for non-successful reply or no reply (timeout)
5101 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5103 ToolboxIstwiReadWriteRequest_t *pReq;
5105 struct pci_dev *pdev;
5106 unsigned long flags;
5111 /* Prevent calling wait_event() (below), if caller happens
5112 * to be in ISR context, because that is fatal!
5114 in_isr = in_interrupt();
5116 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
5121 /* Get and Populate a free Frame
5123 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5124 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
5128 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
5129 pReq->Tool = pCfg->action;
5131 pReq->ChainOffset = 0;
5132 pReq->Function = MPI_FUNCTION_TOOLBOX;
5133 pReq->Reserved1 = 0;
5134 pReq->Reserved2 = 0;
5136 pReq->Flags = pCfg->dir;
5138 pReq->Reserved3 = 0;
5139 pReq->NumAddressBytes = 0x01;
5140 pReq->Reserved4 = 0;
5141 pReq->DataLength = cpu_to_le16(0x04);
5143 if (pdev->devfn & 1)
5144 pReq->DeviceAddr = 0xB2;
5146 pReq->DeviceAddr = 0xB0;
5150 pReq->Reserved5 = 0;
5152 /* Add a SGE to the config request.
5155 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
5157 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
5159 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
5160 ioc->name, pReq->Tool));
5162 /* Append pCfg pointer to end of mf
5164 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5166 /* Initalize the timer
5168 init_timer(&pCfg->timer);
5169 pCfg->timer.data = (unsigned long) ioc;
5170 pCfg->timer.function = mpt_timer_expired;
5171 pCfg->wait_done = 0;
5173 /* Set the timer; ensure 10 second minimum */
5174 if (pCfg->timeout < 10)
5175 pCfg->timer.expires = jiffies + HZ*10;
5177 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5179 /* Add to end of Q, set timer and then issue this command */
5180 spin_lock_irqsave(&ioc->FreeQlock, flags);
5181 list_add_tail(&pCfg->linkage, &ioc->configQ);
5182 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5184 add_timer(&pCfg->timer);
5185 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5186 wait_event(mpt_waitq, pCfg->wait_done);
5188 /* mf has been freed - do not access */
5195 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5197 * mpt_timer_expired - Call back for timer process.
5198 * Used only internal config functionality.
5199 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5202 mpt_timer_expired(unsigned long data)
5204 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5206 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5208 /* Perform a FW reload */
5209 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5210 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5212 /* No more processing.
5213 * Hard reset clean-up will wake up
5214 * process and free all resources.
5216 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5223 * mpt_ioc_reset - Base cleanup for hard reset
5224 * @ioc: Pointer to the adapter structure
5225 * @reset_phase: Indicates pre- or post-reset functionality
5227 * Remark: Free's resources with internally generated commands.
5230 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5233 unsigned long flags;
5235 dprintk((KERN_WARNING MYNAM
5236 ": IOC %s_reset routed to MPT base driver!\n",
5237 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5238 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5240 if (reset_phase == MPT_IOC_SETUP_RESET) {
5242 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5243 /* If the internal config Q is not empty -
5244 * delete timer. MF resources will be freed when
5245 * the FIFO's are primed.
5247 spin_lock_irqsave(&ioc->FreeQlock, flags);
5248 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5249 del_timer(&pCfg->timer);
5250 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5255 /* Search the configQ for internal commands.
5256 * Flush the Q, and wake up all suspended threads.
5258 spin_lock_irqsave(&ioc->FreeQlock, flags);
5259 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5260 list_del(&pCfg->linkage);
5262 pCfg->status = MPT_CONFIG_ERROR;
5263 pCfg->wait_done = 1;
5264 wake_up(&mpt_waitq);
5266 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5269 return 1; /* currently means nothing really */
5273 #ifdef CONFIG_PROC_FS /* { */
5274 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5276 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5278 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5280 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5282 * Returns 0 for success, non-zero for failure.
5285 procmpt_create(void)
5287 struct proc_dir_entry *ent;
5289 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5290 if (mpt_proc_root_dir == NULL)
5293 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5295 ent->read_proc = procmpt_summary_read;
5297 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5299 ent->read_proc = procmpt_version_read;
5304 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5306 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5308 * Returns 0 for success, non-zero for failure.
5311 procmpt_destroy(void)
5313 remove_proc_entry("version", mpt_proc_root_dir);
5314 remove_proc_entry("summary", mpt_proc_root_dir);
5315 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5318 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5320 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5321 * or from /proc/mpt/iocN/summary.
5322 * @buf: Pointer to area to write information
5323 * @start: Pointer to start pointer
5324 * @offset: Offset to start writing
5326 * @eof: Pointer to EOF integer
5329 * Returns number of characters written to process performing the read.
5332 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5342 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5346 list_for_each_entry(ioc, &ioc_list, list) {
5349 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5352 if ((out-buf) >= request)
5359 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5362 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5364 * procmpt_version_read - Handle read request from /proc/mpt/version.
5365 * @buf: Pointer to area to write information
5366 * @start: Pointer to start pointer
5367 * @offset: Offset to start writing
5369 * @eof: Pointer to EOF integer
5372 * Returns number of characters written to process performing the read.
5375 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5378 int scsi, fc, sas, lan, ctl, targ, dmp;
5382 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5383 len += sprintf(buf+len, " Fusion MPT base driver\n");
5385 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5386 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5388 if (MptCallbacks[ii]) {
5389 switch (MptDriverClass[ii]) {
5391 if (!scsi++) drvname = "SPI host";
5394 if (!fc++) drvname = "FC host";
5397 if (!sas++) drvname = "SAS host";
5400 if (!lan++) drvname = "LAN";
5403 if (!targ++) drvname = "SCSI target";
5406 if (!ctl++) drvname = "ioctl";
5411 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5415 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5418 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5420 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5421 * @buf: Pointer to area to write information
5422 * @start: Pointer to start pointer
5423 * @offset: Offset to start writing
5425 * @eof: Pointer to EOF integer
5428 * Returns number of characters written to process performing the read.
5431 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5433 MPT_ADAPTER *ioc = data;
5439 mpt_get_fw_exp_ver(expVer, ioc);
5441 len = sprintf(buf, "%s:", ioc->name);
5442 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5443 len += sprintf(buf+len, " (f/w download boot flag set)");
5444 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5445 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5447 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5448 ioc->facts.ProductID,
5450 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5451 if (ioc->facts.FWImageSize)
5452 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5453 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5454 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5455 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5457 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5458 ioc->facts.CurrentHostMfaHighAddr);
5459 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5460 ioc->facts.CurrentSenseBufferHighAddr);
5462 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5463 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5465 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5466 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5468 * Rounding UP to nearest 4-kB boundary here...
5470 sz = (ioc->req_sz * ioc->req_depth) + 128;
5471 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5472 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5473 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5474 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5475 4*ioc->facts.RequestFrameSize,
5476 ioc->facts.GlobalCredits);
5478 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5479 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5480 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5481 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5482 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5483 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5484 ioc->facts.CurReplyFrameSize,
5485 ioc->facts.ReplyQueueDepth);
5487 len += sprintf(buf+len, " MaxDevices = %d\n",
5488 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5489 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5492 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5493 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5495 ioc->facts.NumberOfPorts);
5496 if (ioc->bus_type == FC) {
5497 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5498 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5499 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5500 a[5], a[4], a[3], a[2], a[1], a[0]);
5502 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5503 ioc->fc_port_page0[p].WWNN.High,
5504 ioc->fc_port_page0[p].WWNN.Low,
5505 ioc->fc_port_page0[p].WWPN.High,
5506 ioc->fc_port_page0[p].WWPN.Low);
5510 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5513 #endif /* CONFIG_PROC_FS } */
5515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5517 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5520 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5521 sprintf(buf, " (Exp %02d%02d)",
5522 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5523 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5526 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5527 strcat(buf, " [MDBG]");
5531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5533 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5534 * @ioc: Pointer to MPT_ADAPTER structure
5535 * @buffer: Pointer to buffer where IOC summary info should be written
5536 * @size: Pointer to number of bytes we wrote (set by this routine)
5537 * @len: Offset at which to start writing in buffer
5538 * @showlan: Display LAN stuff?
5540 * This routine writes (english readable) ASCII text, which represents
5541 * a summary of IOC information, to a buffer.
5544 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5549 mpt_get_fw_exp_ver(expVer, ioc);
5552 * Shorter summary of attached ioc's...
5554 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5557 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5558 ioc->facts.FWVersion.Word,
5560 ioc->facts.NumberOfPorts,
5563 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5564 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5565 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5566 a[5], a[4], a[3], a[2], a[1], a[0]);
5570 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5572 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5576 y += sprintf(buffer+len+y, " (disabled)");
5578 y += sprintf(buffer+len+y, "\n");
5583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5589 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5590 * Management call based on input arg values. If TaskMgmt fails,
5591 * return associated SCSI request.
5592 * @ioc: Pointer to MPT_ADAPTER structure
5593 * @sleepFlag: Indicates if sleep or schedule must be called.
5595 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5596 * or a non-interrupt thread. In the former, must not call schedule().
5598 * Remark: A return of -1 is a FATAL error case, as it means a
5599 * FW reload/initialization failed.
5601 * Returns 0 for SUCCESS or -1 if FAILED.
5604 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5607 unsigned long flags;
5609 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5611 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5612 printk("MF count 0x%x !\n", ioc->mfcnt);
5615 /* Reset the adapter. Prevent more than 1 call to
5616 * mpt_do_ioc_recovery at any instant in time.
5618 spin_lock_irqsave(&ioc->diagLock, flags);
5619 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5620 spin_unlock_irqrestore(&ioc->diagLock, flags);
5623 ioc->diagPending = 1;
5625 spin_unlock_irqrestore(&ioc->diagLock, flags);
5627 /* FIXME: If do_ioc_recovery fails, repeat....
5630 /* The SCSI driver needs to adjust timeouts on all current
5631 * commands prior to the diagnostic reset being issued.
5632 * Prevents timeouts occuring during a diagnostic reset...very bad.
5633 * For all other protocol drivers, this is a no-op.
5639 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5640 if (MptResetHandlers[ii]) {
5641 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5643 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5645 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5646 ioc->name, ioc->alt_ioc->name, ii));
5647 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5653 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5654 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5659 ioc->alt_ioc->reload_fw = 0;
5661 spin_lock_irqsave(&ioc->diagLock, flags);
5662 ioc->diagPending = 0;
5664 ioc->alt_ioc->diagPending = 0;
5665 spin_unlock_irqrestore(&ioc->diagLock, flags);
5667 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5674 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5679 case MPI_EVENT_NONE:
5682 case MPI_EVENT_LOG_DATA:
5685 case MPI_EVENT_STATE_CHANGE:
5686 ds = "State Change";
5688 case MPI_EVENT_UNIT_ATTENTION:
5689 ds = "Unit Attention";
5691 case MPI_EVENT_IOC_BUS_RESET:
5692 ds = "IOC Bus Reset";
5694 case MPI_EVENT_EXT_BUS_RESET:
5695 ds = "External Bus Reset";
5697 case MPI_EVENT_RESCAN:
5698 ds = "Bus Rescan Event";
5699 /* Ok, do we need to do anything here? As far as
5700 I can tell, this is when a new device gets added
5703 case MPI_EVENT_LINK_STATUS_CHANGE:
5704 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5705 ds = "Link Status(FAILURE) Change";
5707 ds = "Link Status(ACTIVE) Change";
5709 case MPI_EVENT_LOOP_STATE_CHANGE:
5710 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5711 ds = "Loop State(LIP) Change";
5712 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5713 ds = "Loop State(LPE) Change"; /* ??? */
5715 ds = "Loop State(LPB) Change"; /* ??? */
5717 case MPI_EVENT_LOGOUT:
5720 case MPI_EVENT_EVENT_CHANGE:
5722 ds = "Events(ON) Change";
5724 ds = "Events(OFF) Change";
5726 case MPI_EVENT_INTEGRATED_RAID:
5728 u8 ReasonCode = (u8)(evData0 >> 16);
5729 switch (ReasonCode) {
5730 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5731 ds = "Integrated Raid: Volume Created";
5733 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5734 ds = "Integrated Raid: Volume Deleted";
5736 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5737 ds = "Integrated Raid: Volume Settings Changed";
5739 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5740 ds = "Integrated Raid: Volume Status Changed";
5742 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5743 ds = "Integrated Raid: Volume Physdisk Changed";
5745 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5746 ds = "Integrated Raid: Physdisk Created";
5748 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5749 ds = "Integrated Raid: Physdisk Deleted";
5751 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5752 ds = "Integrated Raid: Physdisk Settings Changed";
5754 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5755 ds = "Integrated Raid: Physdisk Status Changed";
5757 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5758 ds = "Integrated Raid: Domain Validation Needed";
5760 case MPI_EVENT_RAID_RC_SMART_DATA :
5761 ds = "Integrated Raid; Smart Data";
5763 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5764 ds = "Integrated Raid: Replace Action Started";
5767 ds = "Integrated Raid";
5772 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5773 ds = "SCSI Device Status Change";
5775 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5777 u8 ReasonCode = (u8)(evData0 >> 16);
5778 switch (ReasonCode) {
5779 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5780 ds = "SAS Device Status Change: Added";
5782 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5783 ds = "SAS Device Status Change: Deleted";
5785 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5786 ds = "SAS Device Status Change: SMART Data";
5788 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5789 ds = "SAS Device Status Change: No Persistancy Added";
5792 ds = "SAS Device Status Change: Unknown";
5797 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5798 ds = "Bus Timer Expired";
5800 case MPI_EVENT_QUEUE_FULL:
5803 case MPI_EVENT_SAS_SES:
5804 ds = "SAS SES Event";
5806 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5807 ds = "Persistent Table Full";
5809 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5810 ds = "SAS PHY Link Status";
5812 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5813 ds = "SAS Discovery Error";
5817 * MPT base "custom" events may be added here...
5826 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5828 * ProcessEventNotification - Route a received EventNotificationReply to
5829 * all currently regeistered event handlers.
5830 * @ioc: Pointer to MPT_ADAPTER structure
5831 * @pEventReply: Pointer to EventNotification reply frame
5832 * @evHandlers: Pointer to integer, number of event handlers
5834 * Returns sum of event handlers return values.
5837 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5849 * Do platform normalization of values
5851 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5852 // evCtx = le32_to_cpu(pEventReply->EventContext);
5853 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5855 evData0 = le32_to_cpu(pEventReply->Data[0]);
5858 EventDescriptionStr(event, evData0, evStr);
5859 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5864 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5865 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5866 for (ii = 0; ii < evDataLen; ii++)
5867 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5872 * Do general / base driver event processing
5875 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5877 u8 evState = evData0 & 0xFF;
5879 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5881 /* Update EventState field in cached IocFacts */
5882 if (ioc->facts.Function) {
5883 ioc->facts.EventState = evState;
5892 * Should this event be logged? Events are written sequentially.
5893 * When buffer is full, start again at the top.
5895 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5898 idx = ioc->eventContext % ioc->eventLogSize;
5900 ioc->events[idx].event = event;
5901 ioc->events[idx].eventContext = ioc->eventContext;
5903 for (ii = 0; ii < 2; ii++) {
5905 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5907 ioc->events[idx].data[ii] = 0;
5910 ioc->eventContext++;
5915 * Call each currently registered protocol event handler.
5917 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5918 if (MptEvHandlers[ii]) {
5919 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5921 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5925 /* FIXME? Examine results here? */
5928 * If needed, send (a single) EventAck.
5930 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5931 devtprintk((MYIOC_s_WARN_FMT
5932 "EventAck required\n",ioc->name));
5933 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5934 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5939 *evHandlers = handlers;
5943 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5945 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5946 * @ioc: Pointer to MPT_ADAPTER structure
5947 * @log_info: U32 LogInfo reply word from the IOC
5949 * Refer to lsi/fc_log.h.
5952 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5954 static char *subcl_str[8] = {
5955 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5956 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5958 u8 subcl = (log_info >> 24) & 0x7;
5960 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
5961 ioc->name, log_info, subcl_str[subcl]);
5964 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5966 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5967 * @ioc: Pointer to MPT_ADAPTER structure
5968 * @mr: Pointer to MPT reply frame
5969 * @log_info: U32 LogInfo word from the IOC
5971 * Refer to lsi/sp_log.h.
5974 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5976 u32 info = log_info & 0x00FF0000;
5977 char *desc = "unknown";
5981 desc = "bug! MID not found";
5982 if (ioc->reload_fw == 0)
5987 desc = "Parity Error";
5991 desc = "ASYNC Outbound Overrun";
5995 desc = "SYNC Offset Error";
6003 desc = "Msg In Overflow";
6011 desc = "Outbound DMA Overrun";
6015 desc = "Task Management";
6019 desc = "Device Problem";
6023 desc = "Invalid Phase Change";
6027 desc = "Untagged Table Size";
6032 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6035 /* strings for sas loginfo */
6036 static char *originator_str[] = {
6041 static char *iop_code_str[] = {
6043 "Invalid SAS Address", /* 01h */
6045 "Invalid Page", /* 03h */
6047 "Task Terminated" /* 05h */
6049 static char *pl_code_str[] = {
6051 "Open Failure", /* 01h */
6052 "Invalid Scatter Gather List", /* 02h */
6053 "Wrong Relative Offset or Frame Length", /* 03h */
6054 "Frame Transfer Error", /* 04h */
6055 "Transmit Frame Connected Low", /* 05h */
6056 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6057 "SATA Read Log Receive Data Error", /* 07h */
6058 "SATA NCQ Fail All Commands After Error", /* 08h */
6059 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6060 "Receive Frame Invalid Message", /* 0Ah */
6061 "Receive Context Message Valid Error", /* 0Bh */
6062 "Receive Frame Current Frame Error", /* 0Ch */
6063 "SATA Link Down", /* 0Dh */
6064 "Discovery SATA Init W IOS", /* 0Eh */
6065 "Config Invalid Page", /* 0Fh */
6066 "Discovery SATA Init Timeout", /* 10h */
6069 "IO Not Yet Executed", /* 13h */
6070 "IO Executed", /* 14h */
6082 "Enclosure Management" /* 20h */
6085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6087 * mpt_sas_log_info - Log information returned from SAS IOC.
6088 * @ioc: Pointer to MPT_ADAPTER structure
6089 * @log_info: U32 LogInfo reply word from the IOC
6091 * Refer to lsi/mpi_log_sas.h.
6094 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6096 union loginfo_type {
6105 union loginfo_type sas_loginfo;
6106 char *code_desc = NULL;
6108 sas_loginfo.loginfo = log_info;
6109 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6110 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6112 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6113 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6114 code_desc = iop_code_str[sas_loginfo.dw.code];
6115 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6116 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6117 code_desc = pl_code_str[sas_loginfo.dw.code];
6120 if (code_desc != NULL)
6121 printk(MYIOC_s_INFO_FMT
6122 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6123 " SubCode(0x%04x)\n",
6126 originator_str[sas_loginfo.dw.originator],
6128 sas_loginfo.dw.subcode);
6130 printk(MYIOC_s_INFO_FMT
6131 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6132 " SubCode(0x%04x)\n",
6135 originator_str[sas_loginfo.dw.originator],
6136 sas_loginfo.dw.code,
6137 sas_loginfo.dw.subcode);
6140 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6142 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6143 * @ioc: Pointer to MPT_ADAPTER structure
6144 * @ioc_status: U32 IOCStatus word from IOC
6145 * @mf: Pointer to MPT request frame
6147 * Refer to lsi/mpi.h.
6150 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6152 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6156 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6157 desc = "Invalid Function";
6160 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6164 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6165 desc = "Invalid SGL";
6168 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6169 desc = "Internal Error";
6172 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6176 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6177 desc = "Insufficient Resources";
6180 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6181 desc = "Invalid Field";
6184 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6185 desc = "Invalid State";
6188 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6189 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6190 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6191 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6192 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6193 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6194 /* No message for Config IOCStatus values */
6197 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6198 /* No message for recovered error
6199 desc = "SCSI Recovered Error";
6203 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6204 desc = "SCSI Invalid Bus";
6207 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6208 desc = "SCSI Invalid TargetID";
6211 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6213 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6214 U8 cdb = pScsiReq->CDB[0];
6215 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6216 desc = "SCSI Device Not There";
6221 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6222 desc = "SCSI Data Overrun";
6225 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6226 /* This error is checked in scsi_io_done(). Skip.
6227 desc = "SCSI Data Underrun";
6231 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6232 desc = "SCSI I/O Data Error";
6235 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6236 desc = "SCSI Protocol Error";
6239 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6240 desc = "SCSI Task Terminated";
6243 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6244 desc = "SCSI Residual Mismatch";
6247 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6248 desc = "SCSI Task Management Failed";
6251 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6252 desc = "SCSI IOC Terminated";
6255 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6256 desc = "SCSI Ext Terminated";
6264 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6267 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6268 EXPORT_SYMBOL(mpt_attach);
6269 EXPORT_SYMBOL(mpt_detach);
6271 EXPORT_SYMBOL(mpt_resume);
6272 EXPORT_SYMBOL(mpt_suspend);
6274 EXPORT_SYMBOL(ioc_list);
6275 EXPORT_SYMBOL(mpt_proc_root_dir);
6276 EXPORT_SYMBOL(mpt_register);
6277 EXPORT_SYMBOL(mpt_deregister);
6278 EXPORT_SYMBOL(mpt_event_register);
6279 EXPORT_SYMBOL(mpt_event_deregister);
6280 EXPORT_SYMBOL(mpt_reset_register);
6281 EXPORT_SYMBOL(mpt_reset_deregister);
6282 EXPORT_SYMBOL(mpt_device_driver_register);
6283 EXPORT_SYMBOL(mpt_device_driver_deregister);
6284 EXPORT_SYMBOL(mpt_get_msg_frame);
6285 EXPORT_SYMBOL(mpt_put_msg_frame);
6286 EXPORT_SYMBOL(mpt_free_msg_frame);
6287 EXPORT_SYMBOL(mpt_add_sge);
6288 EXPORT_SYMBOL(mpt_send_handshake_request);
6289 EXPORT_SYMBOL(mpt_verify_adapter);
6290 EXPORT_SYMBOL(mpt_GetIocState);
6291 EXPORT_SYMBOL(mpt_print_ioc_summary);
6292 EXPORT_SYMBOL(mpt_lan_index);
6293 EXPORT_SYMBOL(mpt_stm_index);
6294 EXPORT_SYMBOL(mpt_HardResetHandler);
6295 EXPORT_SYMBOL(mpt_config);
6296 EXPORT_SYMBOL(mpt_toolbox);
6297 EXPORT_SYMBOL(mpt_findImVolumes);
6298 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6299 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6300 EXPORT_SYMBOL(mpt_free_fw_memory);
6301 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6304 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6306 * fusion_init - Fusion MPT base driver initialization routine.
6308 * Returns 0 for success, non-zero for failure.
6315 show_mptmod_ver(my_NAME, my_VERSION);
6316 printk(KERN_INFO COPYRIGHT "\n");
6318 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6319 MptCallbacks[i] = NULL;
6320 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6321 MptEvHandlers[i] = NULL;
6322 MptResetHandlers[i] = NULL;
6325 /* Register ourselves (mptbase) in order to facilitate
6326 * EventNotification handling.
6328 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6330 /* Register for hard reset handling callbacks.
6332 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6333 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6338 #ifdef CONFIG_PROC_FS
6339 (void) procmpt_create();
6344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6346 * fusion_exit - Perform driver unload cleanup.
6348 * This routine frees all resources associated with each MPT adapter
6349 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6355 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6357 mpt_reset_deregister(mpt_base_index);
6359 #ifdef CONFIG_PROC_FS
6364 module_init(fusion_init);
6365 module_exit(fusion_exit);