2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI Logic PCI chip/adapter(s)
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2005 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/config.h>
50 #include <linux/kernel.h>
51 #include <linux/module.h>
52 #include <linux/errno.h>
53 #include <linux/init.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
67 #include <asm/irq.h> /* needed for __irq_itoa() proto */
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
73 #define my_NAME "Fusion MPT base driver"
74 #define my_VERSION MPT_LINUX_VERSION_COMMON
75 #define MYNAM "mptbase"
77 MODULE_AUTHOR(MODULEAUTHOR);
78 MODULE_DESCRIPTION(my_NAME);
79 MODULE_LICENSE("GPL");
85 static int mfcounter = 0;
86 #define PRINT_MF_COUNT 20000
89 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
93 int mpt_lan_index = -1;
94 int mpt_stm_index = -1;
96 struct proc_dir_entry *mpt_proc_root_dir;
98 #define WHOINIT_UNKNOWN 0xAA
100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
104 /* Adapter link list */
106 /* Callback lookup table */
107 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
108 /* Protocol driver class lookup table */
109 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
110 /* Event handler lookup table */
111 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
112 /* Reset handler lookup table */
113 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
114 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
116 static int mpt_base_index = -1;
117 static int last_drv_idx = -1;
119 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
121 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
125 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
126 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
127 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
128 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
130 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
131 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
132 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
133 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
135 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
136 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
137 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
138 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
139 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
140 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
141 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
142 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
143 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
144 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
145 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
146 static int PrimeIocFifos(MPT_ADAPTER *ioc);
147 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
148 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
149 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
150 static int GetLanConfigPages(MPT_ADAPTER *ioc);
151 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
152 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
153 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
154 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
155 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
156 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
157 static void mpt_timer_expired(unsigned long data);
158 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
159 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
160 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
161 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
163 #ifdef CONFIG_PROC_FS
164 static int procmpt_summary_read(char *buf, char **start, off_t offset,
165 int request, int *eof, void *data);
166 static int procmpt_version_read(char *buf, char **start, off_t offset,
167 int request, int *eof, void *data);
168 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
169 int request, int *eof, void *data);
171 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
173 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
174 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
175 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
176 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
177 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
178 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
180 /* module entry point */
181 static int __init fusion_init (void);
182 static void __exit fusion_exit (void);
184 #define CHIPREG_READ32(addr) readl_relaxed(addr)
185 #define CHIPREG_READ32_dmasync(addr) readl(addr)
186 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
187 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
188 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
191 pci_disable_io_access(struct pci_dev *pdev)
195 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
197 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
201 pci_enable_io_access(struct pci_dev *pdev)
205 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
207 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
211 * Process turbo (context) reply...
214 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
216 MPT_FRAME_HDR *mf = NULL;
217 MPT_FRAME_HDR *mr = NULL;
221 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
224 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
225 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
226 req_idx = pa & 0x0000FFFF;
227 cb_idx = (pa & 0x00FF0000) >> 16;
228 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
230 case MPI_CONTEXT_REPLY_TYPE_LAN:
231 cb_idx = mpt_lan_index;
233 * Blind set of mf to NULL here was fatal
234 * after lan_reply says "freeme"
235 * Fix sort of combined with an optimization here;
236 * added explicit check for case where lan_reply
237 * was just returning 1 and doing nothing else.
238 * For this case skip the callback, but set up
239 * proper mf value first here:-)
241 if ((pa & 0x58000000) == 0x58000000) {
242 req_idx = pa & 0x0000FFFF;
243 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
244 mpt_free_msg_frame(ioc, mf);
249 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
251 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
252 cb_idx = mpt_stm_index;
253 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
260 /* Check for (valid) IO callback! */
261 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
262 MptCallbacks[cb_idx] == NULL) {
263 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
264 __FUNCTION__, ioc->name, cb_idx);
268 if (MptCallbacks[cb_idx](ioc, mf, mr))
269 mpt_free_msg_frame(ioc, mf);
275 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
286 /* non-TURBO reply! Hmmm, something may be up...
287 * Newest turbo reply mechanism; get address
288 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
291 /* Map DMA address of reply header to cpu address.
292 * pa is 32 bits - but the dma address may be 32 or 64 bits
293 * get offset based only only the low addresses
296 reply_dma_low = (pa <<= 1);
297 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
298 (reply_dma_low - ioc->reply_frames_low_dma));
300 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
301 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
302 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
304 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
305 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
306 DBG_DUMP_REPLY_FRAME(mr)
308 /* Check/log IOC log info
310 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
311 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
312 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
313 if (ioc->bus_type == FC)
314 mpt_fc_log_info(ioc, log_info);
315 else if (ioc->bus_type == SPI)
316 mpt_sp_log_info(ioc, log_info);
317 else if (ioc->bus_type == SAS)
318 mpt_sas_log_info(ioc, log_info);
320 if (ioc_stat & MPI_IOCSTATUS_MASK) {
321 if (ioc->bus_type == SPI &&
322 cb_idx != mpt_stm_index &&
323 cb_idx != mpt_lan_index)
324 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
328 /* Check for (valid) IO callback! */
329 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
330 MptCallbacks[cb_idx] == NULL) {
331 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
332 __FUNCTION__, ioc->name, cb_idx);
337 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
340 /* Flush (non-TURBO) reply with a WRITE! */
341 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
344 mpt_free_msg_frame(ioc, mf);
348 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
350 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
351 * @irq: irq number (not used)
352 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
353 * @r: pt_regs pointer (not used)
355 * This routine is registered via the request_irq() kernel API call,
356 * and handles all interrupts generated from a specific MPT adapter
357 * (also referred to as a IO Controller or IOC).
358 * This routine must clear the interrupt from the adapter and does
359 * so by reading the reply FIFO. Multiple replies may be processed
360 * per single call to this routine.
362 * This routine handles register-level access of the adapter but
363 * dispatches (calls) a protocol-specific callback routine to handle
364 * the protocol-specific details of the MPT request completion.
367 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
369 MPT_ADAPTER *ioc = bus_id;
373 * Drain the reply FIFO!
376 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
377 if (pa == 0xFFFFFFFF)
379 else if (pa & MPI_ADDRESS_REPLY_A_BIT)
382 mpt_turbo_reply(ioc, pa);
388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
390 * mpt_base_reply - MPT base driver's callback routine; all base driver
391 * "internal" request/reply processing is routed here.
392 * Currently used for EventNotification and EventAck handling.
393 * @ioc: Pointer to MPT_ADAPTER structure
394 * @mf: Pointer to original MPT request frame
395 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
397 * Returns 1 indicating original alloc'd request frame ptr
398 * should be freed, or 0 if it shouldn't.
401 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
406 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
408 #if defined(MPT_DEBUG_MSG_FRAME)
409 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
410 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
411 DBG_DUMP_REQUEST_FRAME_HDR(mf)
415 func = reply->u.hdr.Function;
416 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
419 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
420 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
424 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
425 if (results != evHandlers) {
426 /* CHECKME! Any special handling needed here? */
427 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
428 ioc->name, evHandlers, results));
432 * Hmmm... It seems that EventNotificationReply is an exception
433 * to the rule of one reply per request.
435 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
437 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
438 ioc->name, pEvReply));
440 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
441 ioc->name, pEvReply));
444 #ifdef CONFIG_PROC_FS
445 // LogEvent(ioc, pEvReply);
448 } else if (func == MPI_FUNCTION_EVENT_ACK) {
449 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
451 } else if (func == MPI_FUNCTION_CONFIG ||
452 func == MPI_FUNCTION_TOOLBOX) {
456 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
457 ioc->name, mf, reply));
459 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
462 /* disable timer and remove from linked list */
463 del_timer(&pCfg->timer);
465 spin_lock_irqsave(&ioc->FreeQlock, flags);
466 list_del(&pCfg->linkage);
467 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
470 * If IOC Status is SUCCESS, save the header
471 * and set the status code to GOOD.
473 pCfg->status = MPT_CONFIG_ERROR;
475 ConfigReply_t *pReply = (ConfigReply_t *)reply;
478 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
479 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
480 status, le32_to_cpu(pReply->IOCLogInfo)));
482 pCfg->status = status;
483 if (status == MPI_IOCSTATUS_SUCCESS) {
484 if ((pReply->Header.PageType &
485 MPI_CONFIG_PAGETYPE_MASK) ==
486 MPI_CONFIG_PAGETYPE_EXTENDED) {
487 pCfg->cfghdr.ehdr->ExtPageLength =
488 le16_to_cpu(pReply->ExtPageLength);
489 pCfg->cfghdr.ehdr->ExtPageType =
492 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
494 /* If this is a regular header, save PageLength. */
495 /* LMP Do this better so not using a reserved field! */
496 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
497 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
498 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
503 * Wake up the original calling thread
508 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
509 /* we should be always getting a reply frame */
510 memcpy(ioc->persist_reply_frame, reply,
511 min(MPT_DEFAULT_FRAME_SIZE,
512 4*reply->u.reply.MsgLength));
513 del_timer(&ioc->persist_timer);
514 ioc->persist_wait_done = 1;
517 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
522 * Conditionally tell caller to free the original
523 * EventNotification/EventAck/unexpected request frame!
528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
530 * mpt_register - Register protocol-specific main callback handler.
531 * @cbfunc: callback function pointer
532 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
534 * This routine is called by a protocol-specific driver (SCSI host,
535 * LAN, SCSI target) to register it's reply callback routine. Each
536 * protocol-specific driver must do this before it will be able to
537 * use any IOC resources, such as obtaining request frames.
539 * NOTES: The SCSI protocol driver currently calls this routine thrice
540 * in order to register separate callbacks; one for "normal" SCSI IO;
541 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
543 * Returns a positive integer valued "handle" in the
544 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
545 * Any non-positive return value (including zero!) should be considered
546 * an error by the caller.
549 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
556 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
557 * (slot/handle 0 is reserved!)
559 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
560 if (MptCallbacks[i] == NULL) {
561 MptCallbacks[i] = cbfunc;
562 MptDriverClass[i] = dclass;
563 MptEvHandlers[i] = NULL;
572 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
574 * mpt_deregister - Deregister a protocol drivers resources.
575 * @cb_idx: previously registered callback handle
577 * Each protocol-specific driver should call this routine when it's
578 * module is unloaded.
581 mpt_deregister(int cb_idx)
583 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
584 MptCallbacks[cb_idx] = NULL;
585 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
586 MptEvHandlers[cb_idx] = NULL;
592 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
594 * mpt_event_register - Register protocol-specific event callback
596 * @cb_idx: previously registered (via mpt_register) callback handle
597 * @ev_cbfunc: callback function
599 * This routine can be called by one or more protocol-specific drivers
600 * if/when they choose to be notified of MPT events.
602 * Returns 0 for success.
605 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
607 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
610 MptEvHandlers[cb_idx] = ev_cbfunc;
614 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
616 * mpt_event_deregister - Deregister protocol-specific event callback
618 * @cb_idx: previously registered callback handle
620 * Each protocol-specific driver should call this routine
621 * when it does not (or can no longer) handle events,
622 * or when it's module is unloaded.
625 mpt_event_deregister(int cb_idx)
627 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
630 MptEvHandlers[cb_idx] = NULL;
633 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
635 * mpt_reset_register - Register protocol-specific IOC reset handler.
636 * @cb_idx: previously registered (via mpt_register) callback handle
637 * @reset_func: reset function
639 * This routine can be called by one or more protocol-specific drivers
640 * if/when they choose to be notified of IOC resets.
642 * Returns 0 for success.
645 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
647 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
650 MptResetHandlers[cb_idx] = reset_func;
654 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
656 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
657 * @cb_idx: previously registered callback handle
659 * Each protocol-specific driver should call this routine
660 * when it does not (or can no longer) handle IOC reset handling,
661 * or when it's module is unloaded.
664 mpt_reset_deregister(int cb_idx)
666 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
669 MptResetHandlers[cb_idx] = NULL;
672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
674 * mpt_device_driver_register - Register device driver hooks
677 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
681 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
685 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
687 /* call per pci device probe entry point */
688 list_for_each_entry(ioc, &ioc_list, list) {
689 if(dd_cbfunc->probe) {
690 dd_cbfunc->probe(ioc->pcidev,
691 ioc->pcidev->driver->id_table);
698 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
700 * mpt_device_driver_deregister - DeRegister device driver hooks
703 mpt_device_driver_deregister(int cb_idx)
705 struct mpt_pci_driver *dd_cbfunc;
708 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
711 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
713 list_for_each_entry(ioc, &ioc_list, list) {
714 if (dd_cbfunc->remove)
715 dd_cbfunc->remove(ioc->pcidev);
718 MptDeviceDriverHandlers[cb_idx] = NULL;
722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
724 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
725 * allocated per MPT adapter.
726 * @handle: Handle of registered MPT protocol driver
727 * @ioc: Pointer to MPT adapter structure
729 * Returns pointer to a MPT request frame or %NULL if none are available
730 * or IOC is not active.
733 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
737 u16 req_idx; /* Request index */
739 /* validate handle and ioc identifier */
743 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
746 /* If interrupts are not attached, do not return a request frame */
750 spin_lock_irqsave(&ioc->FreeQlock, flags);
751 if (!list_empty(&ioc->FreeQ)) {
754 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
755 u.frame.linkage.list);
756 list_del(&mf->u.frame.linkage.list);
757 mf->u.frame.linkage.arg1 = 0;
758 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
759 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
761 req_idx = req_offset / ioc->req_sz;
762 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
763 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
764 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
771 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
775 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
777 if (mfcounter == PRINT_MF_COUNT)
778 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
781 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
782 ioc->name, handle, ioc->id, mf));
786 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
788 * mpt_put_msg_frame - Send a protocol specific MPT request frame
790 * @handle: Handle of registered MPT protocol driver
791 * @ioc: Pointer to MPT adapter structure
792 * @mf: Pointer to MPT request frame
794 * This routine posts a MPT request frame to the request post FIFO of a
795 * specific MPT adapter.
798 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
802 u16 req_idx; /* Request index */
804 /* ensure values are reset properly! */
805 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
806 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
808 req_idx = req_offset / ioc->req_sz;
809 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
810 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
812 #ifdef MPT_DEBUG_MSG_FRAME
814 u32 *m = mf->u.frame.hwhdr.__hdr;
817 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
819 n = ioc->req_sz/4 - 1;
822 for (ii=0; ii<=n; ii++) {
823 if (ii && ((ii%8)==0))
824 printk("\n" KERN_INFO " ");
825 printk(" %08x", le32_to_cpu(m[ii]));
831 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
832 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]));
833 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
838 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
839 * @handle: Handle of registered MPT protocol driver
840 * @ioc: Pointer to MPT adapter structure
841 * @mf: Pointer to MPT request frame
843 * This routine places a MPT request frame back on the MPT adapter's
847 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
851 /* Put Request back on FreeQ! */
852 spin_lock_irqsave(&ioc->FreeQlock, flags);
853 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
854 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
858 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
861 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
863 * mpt_add_sge - Place a simple SGE at address pAddr.
864 * @pAddr: virtual address for SGE
865 * @flagslength: SGE flags and data transfer length
866 * @dma_addr: Physical address
868 * This routine places a MPT request frame back on the MPT adapter's
872 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
874 if (sizeof(dma_addr_t) == sizeof(u64)) {
875 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
876 u32 tmp = dma_addr & 0xFFFFFFFF;
878 pSge->FlagsLength = cpu_to_le32(flagslength);
879 pSge->Address.Low = cpu_to_le32(tmp);
880 tmp = (u32) ((u64)dma_addr >> 32);
881 pSge->Address.High = cpu_to_le32(tmp);
884 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
885 pSge->FlagsLength = cpu_to_le32(flagslength);
886 pSge->Address = cpu_to_le32(dma_addr);
890 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
892 * mpt_send_handshake_request - Send MPT request via doorbell
894 * @handle: Handle of registered MPT protocol driver
895 * @ioc: Pointer to MPT adapter structure
896 * @reqBytes: Size of the request in bytes
897 * @req: Pointer to MPT request frame
898 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
900 * This routine is used exclusively to send MptScsiTaskMgmt
901 * requests since they are required to be sent via doorbell handshake.
903 * NOTE: It is the callers responsibility to byte-swap fields in the
904 * request which are greater than 1 byte in size.
906 * Returns 0 for success, non-zero for failure.
909 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
915 /* State is known to be good upon entering
916 * this function so issue the bus reset
921 * Emulate what mpt_put_msg_frame() does /wrt to sanity
922 * setting cb_idx/req_idx. But ONLY if this request
923 * is in proper (pre-alloc'd) request buffer range...
925 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
926 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
927 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
928 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
929 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
932 /* Make sure there are no doorbells */
933 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
935 CHIPREG_WRITE32(&ioc->chip->Doorbell,
936 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
937 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
939 /* Wait for IOC doorbell int */
940 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
944 /* Read doorbell and check for active bit */
945 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
948 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
951 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
953 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
957 /* Send request via doorbell handshake */
958 req_as_bytes = (u8 *) req;
959 for (ii = 0; ii < reqBytes/4; ii++) {
962 word = ((req_as_bytes[(ii*4) + 0] << 0) |
963 (req_as_bytes[(ii*4) + 1] << 8) |
964 (req_as_bytes[(ii*4) + 2] << 16) |
965 (req_as_bytes[(ii*4) + 3] << 24));
966 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
967 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
973 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
978 /* Make sure there are no doorbells */
979 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
984 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
986 * mpt_host_page_access_control - provides mechanism for the host
987 * driver to control the IOC's Host Page Buffer access.
988 * @ioc: Pointer to MPT adapter structure
989 * @access_control_value: define bits below
991 * Access Control Value - bits[15:12]
993 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
994 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
995 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
997 * Returns 0 for success, non-zero for failure.
1001 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1005 /* return if in use */
1006 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1007 & MPI_DOORBELL_ACTIVE)
1010 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1012 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1013 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1014 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1015 (access_control_value<<12)));
1017 /* Wait for IOC to clear Doorbell Status bit */
1018 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1024 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1026 * mpt_host_page_alloc - allocate system memory for the fw
1027 * If we already allocated memory in past, then resend the same pointer.
1028 * ioc@: Pointer to pointer to IOC adapter
1029 * ioc_init@: Pointer to ioc init config page
1031 * Returns 0 for success, non-zero for failure.
1034 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1038 u32 host_page_buffer_sz=0;
1040 if(!ioc->HostPageBuffer) {
1042 host_page_buffer_sz =
1043 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1045 if(!host_page_buffer_sz)
1046 return 0; /* fw doesn't need any host buffers */
1048 /* spin till we get enough memory */
1049 while(host_page_buffer_sz > 0) {
1051 if((ioc->HostPageBuffer = pci_alloc_consistent(
1053 host_page_buffer_sz,
1054 &ioc->HostPageBuffer_dma)) != NULL) {
1056 dinitprintk((MYIOC_s_INFO_FMT
1057 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1059 ioc->HostPageBuffer,
1060 ioc->HostPageBuffer_dma,
1061 host_page_buffer_sz));
1062 ioc->alloc_total += host_page_buffer_sz;
1063 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1067 host_page_buffer_sz -= (4*1024);
1071 if(!ioc->HostPageBuffer) {
1072 printk(MYIOC_s_ERR_FMT
1073 "Failed to alloc memory for host_page_buffer!\n",
1078 psge = (char *)&ioc_init->HostPageBufferSGE;
1079 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1080 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1081 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1082 MPI_SGE_FLAGS_HOST_TO_IOC |
1083 MPI_SGE_FLAGS_END_OF_BUFFER;
1084 if (sizeof(dma_addr_t) == sizeof(u64)) {
1085 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1087 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1088 flags_length |= ioc->HostPageBuffer_sz;
1089 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1090 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1097 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1098 * the associated MPT adapter structure.
1099 * @iocid: IOC unique identifier (integer)
1100 * @iocpp: Pointer to pointer to IOC adapter
1102 * Returns iocid and sets iocpp.
1105 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1109 list_for_each_entry(ioc,&ioc_list,list) {
1110 if (ioc->id == iocid) {
1121 mpt_alt_ioc_wait(MPT_ADAPTER *ioc)
1123 int loop_count = 30 * 4; /* Wait 30 seconds */
1124 int status = -1; /* -1 means failed to get board READY */
1127 spin_lock(&ioc->initializing_hba_lock);
1128 if (ioc->initializing_hba_lock_flag == 0) {
1129 ioc->initializing_hba_lock_flag=1;
1130 spin_unlock(&ioc->initializing_hba_lock);
1134 spin_unlock(&ioc->initializing_hba_lock);
1135 set_current_state(TASK_INTERRUPTIBLE);
1136 schedule_timeout(HZ/4);
1137 } while (--loop_count);
1142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1144 * mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery
1145 * @ioc: Pointer to MPT adapter structure
1146 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1148 * This routine performs all the steps necessary to bring the IOC
1149 * to a OPERATIONAL state.
1151 * Special Note: This function was added with spin lock's so as to allow
1152 * the dv(domain validation) work thread to succeed on the other channel
1153 * that maybe occuring at the same time when this function is called.
1154 * Without this lock, the dv would fail when message frames were
1155 * requested during hba bringup on the alternate ioc.
1158 mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag)
1163 if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0))
1167 r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1171 spin_lock(&ioc->alt_ioc->initializing_hba_lock);
1172 ioc->alt_ioc->initializing_hba_lock_flag=0;
1173 spin_unlock(&ioc->alt_ioc->initializing_hba_lock);
1179 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1181 * mpt_attach - Install a PCI intelligent MPT adapter.
1182 * @pdev: Pointer to pci_dev structure
1184 * This routine performs all the steps necessary to bring the IOC of
1185 * a MPT adapter to a OPERATIONAL state. This includes registering
1186 * memory regions, registering the interrupt, and allocating request
1187 * and reply memory pools.
1189 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1192 * Returns 0 for success, non-zero for failure.
1194 * TODO: Add support for polled controllers
1197 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1201 unsigned long mem_phys;
1209 static int mpt_ids = 0;
1210 #ifdef CONFIG_PROC_FS
1211 struct proc_dir_entry *dent, *ent;
1214 if (pci_enable_device(pdev))
1217 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1219 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1220 dprintk((KERN_INFO MYNAM
1221 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1222 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1223 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1227 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1228 dprintk((KERN_INFO MYNAM
1229 ": Using 64 bit consistent mask\n"));
1231 dprintk((KERN_INFO MYNAM
1232 ": Not using 64 bit consistent mask\n"));
1234 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1236 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1239 ioc->alloc_total = sizeof(MPT_ADAPTER);
1240 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1241 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1244 ioc->diagPending = 0;
1245 spin_lock_init(&ioc->diagLock);
1246 spin_lock_init(&ioc->fc_rescan_work_lock);
1247 spin_lock_init(&ioc->fc_rport_lock);
1248 spin_lock_init(&ioc->initializing_hba_lock);
1250 /* Initialize the event logging.
1252 ioc->eventTypes = 0; /* None */
1253 ioc->eventContext = 0;
1254 ioc->eventLogSize = 0;
1261 ioc->cached_fw = NULL;
1263 /* Initilize SCSI Config Data structure
1265 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1267 /* Initialize the running configQ head.
1269 INIT_LIST_HEAD(&ioc->configQ);
1271 /* Initialize the fc rport list head.
1273 INIT_LIST_HEAD(&ioc->fc_rports);
1275 /* Find lookup slot. */
1276 INIT_LIST_HEAD(&ioc->list);
1277 ioc->id = mpt_ids++;
1279 mem_phys = msize = 0;
1281 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1282 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1283 /* Get I/O space! */
1284 port = pci_resource_start(pdev, ii);
1285 psize = pci_resource_len(pdev,ii);
1288 mem_phys = pci_resource_start(pdev, ii);
1289 msize = pci_resource_len(pdev,ii);
1293 ioc->mem_size = msize;
1295 if (ii == DEVICE_COUNT_RESOURCE) {
1296 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1301 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1302 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1305 /* Get logical ptr for PciMem0 space */
1306 /*mem = ioremap(mem_phys, msize);*/
1307 mem = ioremap(mem_phys, 0x100);
1309 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1314 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1316 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1317 &ioc->facts, &ioc->pfacts[0]));
1319 ioc->mem_phys = mem_phys;
1320 ioc->chip = (SYSIF_REGS __iomem *)mem;
1322 /* Save Port IO values in case we need to do downloadboot */
1324 u8 *pmem = (u8*)port;
1325 ioc->pio_mem_phys = port;
1326 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1329 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1330 ioc->prod_name = "LSIFC909";
1333 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1334 ioc->prod_name = "LSIFC929";
1337 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1338 ioc->prod_name = "LSIFC919";
1341 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1342 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1344 if (revision < XL_929) {
1345 ioc->prod_name = "LSIFC929X";
1346 /* 929X Chip Fix. Set Split transactions level
1347 * for PCIX. Set MOST bits to zero.
1349 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1351 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1353 ioc->prod_name = "LSIFC929XL";
1354 /* 929XL Chip Fix. Set MMRBC to 0x08.
1356 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1358 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1361 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1362 ioc->prod_name = "LSIFC919X";
1364 /* 919X Chip Fix. Set Split transactions level
1365 * for PCIX. Set MOST bits to zero.
1367 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1369 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1371 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1372 ioc->prod_name = "LSIFC939X";
1374 ioc->errata_flag_1064 = 1;
1376 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1377 ioc->prod_name = "LSIFC949X";
1379 ioc->errata_flag_1064 = 1;
1381 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1382 ioc->prod_name = "LSI53C1030";
1383 ioc->bus_type = SPI;
1384 /* 1030 Chip Fix. Disable Split transactions
1385 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1387 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1388 if (revision < C0_1030) {
1389 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1391 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1394 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1395 ioc->prod_name = "LSI53C1035";
1396 ioc->bus_type = SPI;
1398 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1399 ioc->prod_name = "LSISAS1064";
1400 ioc->bus_type = SAS;
1401 ioc->errata_flag_1064 = 1;
1403 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
1404 ioc->prod_name = "LSISAS1066";
1405 ioc->bus_type = SAS;
1406 ioc->errata_flag_1064 = 1;
1408 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1409 ioc->prod_name = "LSISAS1068";
1410 ioc->bus_type = SAS;
1411 ioc->errata_flag_1064 = 1;
1413 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1414 ioc->prod_name = "LSISAS1064E";
1415 ioc->bus_type = SAS;
1417 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
1418 ioc->prod_name = "LSISAS1066E";
1419 ioc->bus_type = SAS;
1421 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1422 ioc->prod_name = "LSISAS1068E";
1423 ioc->bus_type = SAS;
1426 if (ioc->errata_flag_1064)
1427 pci_disable_io_access(pdev);
1429 sprintf(ioc->name, "ioc%d", ioc->id);
1431 spin_lock_init(&ioc->FreeQlock);
1434 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1436 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1438 /* Set lookup ptr. */
1439 list_add_tail(&ioc->list, &ioc_list);
1443 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1447 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1448 ioc->name, pdev->irq);
1450 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1451 ioc->name, __irq_itoa(pdev->irq));
1453 list_del(&ioc->list);
1459 ioc->pci_irq = pdev->irq;
1461 pci_set_master(pdev); /* ?? */
1462 pci_set_drvdata(pdev, ioc);
1465 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1467 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1471 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1473 mpt_detect_bound_ports(ioc, pdev);
1475 if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){
1476 printk(KERN_WARNING MYNAM
1477 ": WARNING - %s did not initialize properly! (%d)\n",
1480 list_del(&ioc->list);
1481 free_irq(ioc->pci_irq, ioc);
1484 pci_set_drvdata(pdev, NULL);
1488 /* call per device driver probe entry point */
1489 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1490 if(MptDeviceDriverHandlers[ii] &&
1491 MptDeviceDriverHandlers[ii]->probe) {
1492 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1496 #ifdef CONFIG_PROC_FS
1498 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1500 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1502 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1504 ent->read_proc = procmpt_iocinfo_read;
1507 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1509 ent->read_proc = procmpt_summary_read;
1518 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1520 * mpt_detach - Remove a PCI intelligent MPT adapter.
1521 * @pdev: Pointer to pci_dev structure
1526 mpt_detach(struct pci_dev *pdev)
1528 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1532 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1533 remove_proc_entry(pname, NULL);
1534 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1535 remove_proc_entry(pname, NULL);
1536 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1537 remove_proc_entry(pname, NULL);
1539 /* call per device driver remove entry point */
1540 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1541 if(MptDeviceDriverHandlers[ii] &&
1542 MptDeviceDriverHandlers[ii]->remove) {
1543 MptDeviceDriverHandlers[ii]->remove(pdev);
1547 /* Disable interrupts! */
1548 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1551 synchronize_irq(pdev->irq);
1553 /* Clear any lingering interrupt */
1554 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1556 CHIPREG_READ32(&ioc->chip->IntStatus);
1558 mpt_adapter_dispose(ioc);
1560 pci_set_drvdata(pdev, NULL);
1563 /**************************************************************************
1567 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1569 * mpt_suspend - Fusion MPT base driver suspend routine.
1574 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1577 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1579 device_state=pci_choose_state(pdev, state);
1581 printk(MYIOC_s_INFO_FMT
1582 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1583 ioc->name, pdev, pci_name(pdev), device_state);
1585 pci_save_state(pdev);
1587 /* put ioc into READY_STATE */
1588 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1589 printk(MYIOC_s_ERR_FMT
1590 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1593 /* disable interrupts */
1594 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1597 /* Clear any lingering interrupt */
1598 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1600 pci_disable_device(pdev);
1601 pci_set_power_state(pdev, device_state);
1606 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1608 * mpt_resume - Fusion MPT base driver resume routine.
1613 mpt_resume(struct pci_dev *pdev)
1615 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1616 u32 device_state = pdev->current_state;
1620 printk(MYIOC_s_INFO_FMT
1621 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1622 ioc->name, pdev, pci_name(pdev), device_state);
1624 pci_set_power_state(pdev, 0);
1625 pci_restore_state(pdev);
1626 pci_enable_device(pdev);
1628 /* enable interrupts */
1629 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1632 /* F/W not running */
1633 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1634 /* enable domain validation flags */
1635 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1636 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1640 printk(MYIOC_s_INFO_FMT
1641 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1643 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1644 CHIPREG_READ32(&ioc->chip->Doorbell));
1646 /* bring ioc to operational state */
1647 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1648 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1649 printk(MYIOC_s_INFO_FMT
1650 "pci-resume: Cannot recover, error:[%x]\n",
1651 ioc->name, recovery_state);
1653 printk(MYIOC_s_INFO_FMT
1654 "pci-resume: success\n", ioc->name);
1661 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1663 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1664 * @ioc: Pointer to MPT adapter structure
1665 * @reason: Event word / reason
1666 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1668 * This routine performs all the steps necessary to bring the IOC
1669 * to a OPERATIONAL state.
1671 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1676 * -1 if failed to get board READY
1677 * -2 if READY but IOCFacts Failed
1678 * -3 if READY but PrimeIOCFifos Failed
1679 * -4 if READY but IOCInit Failed
1682 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1684 int hard_reset_done = 0;
1685 int alt_ioc_ready = 0;
1691 int reset_alt_ioc_active = 0;
1693 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1694 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1696 /* Disable reply interrupts (also blocks FreeQ) */
1697 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1701 if (ioc->alt_ioc->active)
1702 reset_alt_ioc_active = 1;
1704 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1705 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1706 ioc->alt_ioc->active = 0;
1710 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1713 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1714 if (hard_reset_done == -4) {
1715 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1718 if (reset_alt_ioc_active && ioc->alt_ioc) {
1719 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1720 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1721 ioc->alt_ioc->name));
1722 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1723 ioc->alt_ioc->active = 1;
1727 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1733 /* hard_reset_done = 0 if a soft reset was performed
1734 * and 1 if a hard reset was performed.
1736 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1737 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1740 printk(KERN_WARNING MYNAM
1741 ": alt-%s: Not ready WARNING!\n",
1742 ioc->alt_ioc->name);
1745 for (ii=0; ii<5; ii++) {
1746 /* Get IOC facts! Allow 5 retries */
1747 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1753 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1755 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1756 MptDisplayIocCapabilities(ioc);
1759 if (alt_ioc_ready) {
1760 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1761 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1762 /* Retry - alt IOC was initialized once
1764 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1767 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1769 reset_alt_ioc_active = 0;
1770 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1771 MptDisplayIocCapabilities(ioc->alt_ioc);
1775 /* Prime reply & request queues!
1776 * (mucho alloc's) Must be done prior to
1777 * init as upper addresses are needed for init.
1778 * If fails, continue with alt-ioc processing
1780 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1783 /* May need to check/upload firmware & data here!
1784 * If fails, continue with alt-ioc processing
1786 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1789 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1790 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1791 ioc->alt_ioc->name, rc);
1793 reset_alt_ioc_active = 0;
1796 if (alt_ioc_ready) {
1797 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1799 reset_alt_ioc_active = 0;
1800 printk(KERN_WARNING MYNAM
1801 ": alt-%s: (%d) init failure WARNING!\n",
1802 ioc->alt_ioc->name, rc);
1806 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1807 if (ioc->upload_fw) {
1808 ddlprintk((MYIOC_s_INFO_FMT
1809 "firmware upload required!\n", ioc->name));
1811 /* Controller is not operational, cannot do upload
1814 rc = mpt_do_upload(ioc, sleepFlag);
1816 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1818 * Maintain only one pointer to FW memory
1819 * so there will not be two attempt to
1820 * downloadboot onboard dual function
1821 * chips (mpt_adapter_disable,
1824 ioc->cached_fw = NULL;
1825 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1826 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1829 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1837 /* Enable! (reply interrupt) */
1838 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1842 if (reset_alt_ioc_active && ioc->alt_ioc) {
1843 /* (re)Enable alt-IOC! (reply interrupt) */
1844 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1845 ioc->alt_ioc->name));
1846 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1847 ioc->alt_ioc->active = 1;
1850 /* Enable MPT base driver management of EventNotification
1851 * and EventAck handling.
1853 if ((ret == 0) && (!ioc->facts.EventState))
1854 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1856 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1857 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1859 /* Add additional "reason" check before call to GetLanConfigPages
1860 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1861 * recursive scenario; GetLanConfigPages times out, timer expired
1862 * routine calls HardResetHandler, which calls into here again,
1863 * and we try GetLanConfigPages again...
1865 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1866 if (ioc->bus_type == SAS) {
1868 /* clear persistency table */
1869 if(ioc->facts.IOCExceptions &
1870 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1871 ret = mptbase_sas_persist_operation(ioc,
1872 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1879 mpt_findImVolumes(ioc);
1881 } else if (ioc->bus_type == FC) {
1883 * Pre-fetch FC port WWN and stuff...
1884 * (FCPortPage0_t stuff)
1886 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1887 (void) mptbase_GetFcPortPage0(ioc, ii);
1890 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1891 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1893 * Pre-fetch the ports LAN MAC address!
1894 * (LANPage1_t stuff)
1896 (void) GetLanConfigPages(ioc);
1899 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1900 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1901 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1906 /* Get NVRAM and adapter maximums from SPP 0 and 2
1908 mpt_GetScsiPortSettings(ioc, 0);
1910 /* Get version and length of SDP 1
1912 mpt_readScsiDevicePageHeaders(ioc, 0);
1916 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1917 mpt_findImVolumes(ioc);
1919 /* Check, and possibly reset, the coalescing value
1921 mpt_read_ioc_pg_1(ioc);
1923 mpt_read_ioc_pg_4(ioc);
1926 GetIoUnitPage2(ioc);
1930 * Call each currently registered protocol IOC reset handler
1931 * with post-reset indication.
1932 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1933 * MptResetHandlers[] registered yet.
1935 if (hard_reset_done) {
1937 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1938 if ((ret == 0) && MptResetHandlers[ii]) {
1939 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1941 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1945 if (alt_ioc_ready && MptResetHandlers[ii]) {
1946 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1947 ioc->name, ioc->alt_ioc->name, ii));
1948 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1952 /* FIXME? Examine results here? */
1958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1960 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1961 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1962 * 929X, 1030 or 1035.
1963 * @ioc: Pointer to MPT adapter structure
1964 * @pdev: Pointer to (struct pci_dev) structure
1966 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1967 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1970 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1972 struct pci_dev *peer=NULL;
1973 unsigned int slot = PCI_SLOT(pdev->devfn);
1974 unsigned int func = PCI_FUNC(pdev->devfn);
1975 MPT_ADAPTER *ioc_srch;
1977 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1978 " searching for devfn match on %x or %x\n",
1979 ioc->name, pci_name(pdev), pdev->bus->number,
1980 pdev->devfn, func-1, func+1));
1982 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1984 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1989 list_for_each_entry(ioc_srch, &ioc_list, list) {
1990 struct pci_dev *_pcidev = ioc_srch->pcidev;
1991 if (_pcidev == peer) {
1992 /* Paranoia checks */
1993 if (ioc->alt_ioc != NULL) {
1994 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1995 ioc->name, ioc->alt_ioc->name);
1997 } else if (ioc_srch->alt_ioc != NULL) {
1998 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1999 ioc_srch->name, ioc_srch->alt_ioc->name);
2002 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2003 ioc->name, ioc_srch->name));
2004 ioc_srch->alt_ioc = ioc;
2005 ioc->alt_ioc = ioc_srch;
2011 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2013 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2014 * @this: Pointer to MPT adapter structure
2017 mpt_adapter_disable(MPT_ADAPTER *ioc)
2022 if (ioc->cached_fw != NULL) {
2023 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2024 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2025 printk(KERN_WARNING MYNAM
2026 ": firmware downloadboot failure (%d)!\n", ret);
2030 /* Disable adapter interrupts! */
2031 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2033 /* Clear any lingering interrupt */
2034 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2036 if (ioc->alloc != NULL) {
2038 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2039 ioc->name, ioc->alloc, ioc->alloc_sz));
2040 pci_free_consistent(ioc->pcidev, sz,
2041 ioc->alloc, ioc->alloc_dma);
2042 ioc->reply_frames = NULL;
2043 ioc->req_frames = NULL;
2045 ioc->alloc_total -= sz;
2048 if (ioc->sense_buf_pool != NULL) {
2049 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2050 pci_free_consistent(ioc->pcidev, sz,
2051 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2052 ioc->sense_buf_pool = NULL;
2053 ioc->alloc_total -= sz;
2056 if (ioc->events != NULL){
2057 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2060 ioc->alloc_total -= sz;
2063 if (ioc->cached_fw != NULL) {
2064 sz = ioc->facts.FWImageSize;
2065 pci_free_consistent(ioc->pcidev, sz,
2066 ioc->cached_fw, ioc->cached_fw_dma);
2067 ioc->cached_fw = NULL;
2068 ioc->alloc_total -= sz;
2071 kfree(ioc->spi_data.nvram);
2072 kfree(ioc->raid_data.pIocPg3);
2073 ioc->spi_data.nvram = NULL;
2074 ioc->raid_data.pIocPg3 = NULL;
2076 if (ioc->spi_data.pIocPg4 != NULL) {
2077 sz = ioc->spi_data.IocPg4Sz;
2078 pci_free_consistent(ioc->pcidev, sz,
2079 ioc->spi_data.pIocPg4,
2080 ioc->spi_data.IocPg4_dma);
2081 ioc->spi_data.pIocPg4 = NULL;
2082 ioc->alloc_total -= sz;
2085 if (ioc->ReqToChain != NULL) {
2086 kfree(ioc->ReqToChain);
2087 kfree(ioc->RequestNB);
2088 ioc->ReqToChain = NULL;
2091 kfree(ioc->ChainToChain);
2092 ioc->ChainToChain = NULL;
2094 if (ioc->HostPageBuffer != NULL) {
2095 if((ret = mpt_host_page_access_control(ioc,
2096 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2097 printk(KERN_ERR MYNAM
2098 ": %s: host page buffers free failed (%d)!\n",
2101 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2102 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2103 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2104 ioc->HostPageBuffer,
2105 ioc->HostPageBuffer_dma);
2106 ioc->HostPageBuffer = NULL;
2107 ioc->HostPageBuffer_sz = 0;
2108 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2114 * mpt_adapter_dispose - Free all resources associated with a MPT
2116 * @ioc: Pointer to MPT adapter structure
2118 * This routine unregisters h/w resources and frees all alloc'd memory
2119 * associated with a MPT adapter structure.
2122 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2124 int sz_first, sz_last;
2129 sz_first = ioc->alloc_total;
2131 mpt_adapter_disable(ioc);
2133 if (ioc->pci_irq != -1) {
2134 free_irq(ioc->pci_irq, ioc);
2138 if (ioc->memmap != NULL) {
2139 iounmap(ioc->memmap);
2143 #if defined(CONFIG_MTRR) && 0
2144 if (ioc->mtrr_reg > 0) {
2145 mtrr_del(ioc->mtrr_reg, 0, 0);
2146 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2150 /* Zap the adapter lookup ptr! */
2151 list_del(&ioc->list);
2153 sz_last = ioc->alloc_total;
2154 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2155 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2159 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2161 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2162 * @ioc: Pointer to MPT adapter structure
2165 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2169 printk(KERN_INFO "%s: ", ioc->name);
2170 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2171 printk("%s: ", ioc->prod_name+3);
2172 printk("Capabilities={");
2174 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2175 printk("Initiator");
2179 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2180 printk("%sTarget", i ? "," : "");
2184 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2185 printk("%sLAN", i ? "," : "");
2191 * This would probably evoke more questions than it's worth
2193 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2194 printk("%sLogBusAddr", i ? "," : "");
2202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2204 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2205 * @ioc: Pointer to MPT_ADAPTER structure
2206 * @force: Force hard KickStart of IOC
2207 * @sleepFlag: Specifies whether the process can sleep
2210 * 1 - DIAG reset and READY
2211 * 0 - READY initially OR soft reset and READY
2212 * -1 - Any failure on KickStart
2213 * -2 - Msg Unit Reset Failed
2214 * -3 - IO Unit Reset Failed
2215 * -4 - IOC owned by a PEER
2218 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2223 int hard_reset_done = 0;
2228 /* Get current [raw] IOC state */
2229 ioc_state = mpt_GetIocState(ioc, 0);
2230 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2233 * Check to see if IOC got left/stuck in doorbell handshake
2234 * grip of death. If so, hard reset the IOC.
2236 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2238 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2242 /* Is it already READY? */
2243 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2247 * Check to see if IOC is in FAULT state.
2249 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2251 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2253 printk(KERN_WARNING " FAULT code = %04xh\n",
2254 ioc_state & MPI_DOORBELL_DATA_MASK);
2258 * Hmmm... Did it get left operational?
2260 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2261 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2265 * If PCI Peer, exit.
2266 * Else, if no fault conditions are present, issue a MessageUnitReset
2267 * Else, fall through to KickStart case
2269 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2270 dinitprintk((KERN_INFO MYNAM
2271 ": whoinit 0x%x statefault %d force %d\n",
2272 whoinit, statefault, force));
2273 if (whoinit == MPI_WHOINIT_PCI_PEER)
2276 if ((statefault == 0 ) && (force == 0)) {
2277 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2284 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2285 if (hard_reset_done < 0)
2289 * Loop here waiting for IOC to come READY.
2292 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2294 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2295 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2297 * BIOS or previous driver load left IOC in OP state.
2298 * Reset messaging FIFOs.
2300 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2301 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2304 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2306 * Something is wrong. Try to get IOC back
2309 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2310 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2317 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2318 ioc->name, (int)((ii+5)/HZ));
2322 if (sleepFlag == CAN_SLEEP) {
2323 msleep_interruptible(1);
2325 mdelay (1); /* 1 msec delay */
2330 if (statefault < 3) {
2331 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2333 statefault==1 ? "stuck handshake" : "IOC FAULT");
2336 return hard_reset_done;
2339 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2341 * mpt_GetIocState - Get the current state of a MPT adapter.
2342 * @ioc: Pointer to MPT_ADAPTER structure
2343 * @cooked: Request raw or cooked IOC state
2345 * Returns all IOC Doorbell register bits if cooked==0, else just the
2346 * Doorbell bits in MPI_IOC_STATE_MASK.
2349 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2354 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2355 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2356 sc = s & MPI_IOC_STATE_MASK;
2359 ioc->last_state = sc;
2361 return cooked ? sc : s;
2364 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2366 * GetIocFacts - Send IOCFacts request to MPT adapter.
2367 * @ioc: Pointer to MPT_ADAPTER structure
2368 * @sleepFlag: Specifies whether the process can sleep
2369 * @reason: If recovery, only update facts.
2371 * Returns 0 for success, non-zero for failure.
2374 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2376 IOCFacts_t get_facts;
2377 IOCFactsReply_t *facts;
2385 /* IOC *must* NOT be in RESET state! */
2386 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2387 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2393 facts = &ioc->facts;
2395 /* Destination (reply area)... */
2396 reply_sz = sizeof(*facts);
2397 memset(facts, 0, reply_sz);
2399 /* Request area (get_facts on the stack right now!) */
2400 req_sz = sizeof(get_facts);
2401 memset(&get_facts, 0, req_sz);
2403 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2404 /* Assert: All other get_facts fields are zero! */
2406 dinitprintk((MYIOC_s_INFO_FMT
2407 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2408 ioc->name, req_sz, reply_sz));
2410 /* No non-zero fields in the get_facts request are greater than
2411 * 1 byte in size, so we can just fire it off as is.
2413 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2414 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2419 * Now byte swap (GRRR) the necessary fields before any further
2420 * inspection of reply contents.
2422 * But need to do some sanity checks on MsgLength (byte) field
2423 * to make sure we don't zero IOC's req_sz!
2425 /* Did we get a valid reply? */
2426 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2427 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2429 * If not been here, done that, save off first WhoInit value
2431 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2432 ioc->FirstWhoInit = facts->WhoInit;
2435 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2436 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2437 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2438 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2439 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2440 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2441 /* CHECKME! IOCStatus, IOCLogInfo */
2443 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2444 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2447 * FC f/w version changed between 1.1 and 1.2
2448 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2449 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2451 if (facts->MsgVersion < 0x0102) {
2453 * Handle old FC f/w style, convert to new...
2455 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2456 facts->FWVersion.Word =
2457 ((oldv<<12) & 0xFF000000) |
2458 ((oldv<<8) & 0x000FFF00);
2460 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2462 facts->ProductID = le16_to_cpu(facts->ProductID);
2463 facts->CurrentHostMfaHighAddr =
2464 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2465 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2466 facts->CurrentSenseBufferHighAddr =
2467 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2468 facts->CurReplyFrameSize =
2469 le16_to_cpu(facts->CurReplyFrameSize);
2470 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2473 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2474 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2475 * to 14 in MPI-1.01.0x.
2477 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2478 facts->MsgVersion > 0x0100) {
2479 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2482 sz = facts->FWImageSize;
2487 facts->FWImageSize = sz;
2489 if (!facts->RequestFrameSize) {
2490 /* Something is wrong! */
2491 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2496 r = sz = facts->BlockSize;
2497 vv = ((63 / (sz * 4)) + 1) & 0x03;
2498 ioc->NB_for_64_byte_frame = vv;
2504 ioc->NBShiftFactor = shiftFactor;
2505 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2506 ioc->name, vv, shiftFactor, r));
2508 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2510 * Set values for this IOC's request & reply frame sizes,
2511 * and request & reply queue depths...
2513 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2514 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2515 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2516 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2518 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2519 ioc->name, ioc->reply_sz, ioc->reply_depth));
2520 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2521 ioc->name, ioc->req_sz, ioc->req_depth));
2523 /* Get port facts! */
2524 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2528 printk(MYIOC_s_ERR_FMT
2529 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2530 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2531 RequestFrameSize)/sizeof(u32)));
2538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2540 * GetPortFacts - Send PortFacts request to MPT adapter.
2541 * @ioc: Pointer to MPT_ADAPTER structure
2542 * @portnum: Port number
2543 * @sleepFlag: Specifies whether the process can sleep
2545 * Returns 0 for success, non-zero for failure.
2548 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2550 PortFacts_t get_pfacts;
2551 PortFactsReply_t *pfacts;
2556 /* IOC *must* NOT be in RESET state! */
2557 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2558 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2564 pfacts = &ioc->pfacts[portnum];
2566 /* Destination (reply area)... */
2567 reply_sz = sizeof(*pfacts);
2568 memset(pfacts, 0, reply_sz);
2570 /* Request area (get_pfacts on the stack right now!) */
2571 req_sz = sizeof(get_pfacts);
2572 memset(&get_pfacts, 0, req_sz);
2574 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2575 get_pfacts.PortNumber = portnum;
2576 /* Assert: All other get_pfacts fields are zero! */
2578 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2579 ioc->name, portnum));
2581 /* No non-zero fields in the get_pfacts request are greater than
2582 * 1 byte in size, so we can just fire it off as is.
2584 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2585 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2589 /* Did we get a valid reply? */
2591 /* Now byte swap the necessary fields in the response. */
2592 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2593 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2594 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2595 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2596 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2597 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2598 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2599 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2600 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2605 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2607 * SendIocInit - Send IOCInit request to MPT adapter.
2608 * @ioc: Pointer to MPT_ADAPTER structure
2609 * @sleepFlag: Specifies whether the process can sleep
2611 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2613 * Returns 0 for success, non-zero for failure.
2616 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2619 MPIDefaultReply_t init_reply;
2625 memset(&ioc_init, 0, sizeof(ioc_init));
2626 memset(&init_reply, 0, sizeof(init_reply));
2628 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2629 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2631 /* If we are in a recovery mode and we uploaded the FW image,
2632 * then this pointer is not NULL. Skip the upload a second time.
2633 * Set this flag if cached_fw set for either IOC.
2635 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2639 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2640 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2642 if(ioc->bus_type == SAS)
2643 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2644 else if(ioc->bus_type == FC)
2645 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2647 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2648 ioc_init.MaxBuses = MPT_MAX_BUS;
2649 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2650 ioc->name, ioc->facts.MsgVersion));
2651 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2652 // set MsgVersion and HeaderVersion host driver was built with
2653 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2654 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2656 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2657 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2658 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2661 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2663 if (sizeof(dma_addr_t) == sizeof(u64)) {
2664 /* Save the upper 32-bits of the request
2665 * (reply) and sense buffers.
2667 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2668 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2670 /* Force 32-bit addressing */
2671 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2672 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2675 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2676 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2677 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2678 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2680 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2681 ioc->name, &ioc_init));
2683 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2684 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2686 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2690 /* No need to byte swap the multibyte fields in the reply
2691 * since we don't even look at it's contents.
2694 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2695 ioc->name, &ioc_init));
2697 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2698 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2702 /* YIKES! SUPER IMPORTANT!!!
2703 * Poll IocState until _OPERATIONAL while IOC is doing
2704 * LoopInit and TargetDiscovery!
2707 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2708 state = mpt_GetIocState(ioc, 1);
2709 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2710 if (sleepFlag == CAN_SLEEP) {
2711 msleep_interruptible(1);
2717 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2718 ioc->name, (int)((count+5)/HZ));
2722 state = mpt_GetIocState(ioc, 1);
2725 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2733 * SendPortEnable - Send PortEnable request to MPT adapter port.
2734 * @ioc: Pointer to MPT_ADAPTER structure
2735 * @portnum: Port number to enable
2736 * @sleepFlag: Specifies whether the process can sleep
2738 * Send PortEnable to bring IOC to OPERATIONAL state.
2740 * Returns 0 for success, non-zero for failure.
2743 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2745 PortEnable_t port_enable;
2746 MPIDefaultReply_t reply_buf;
2751 /* Destination... */
2752 reply_sz = sizeof(MPIDefaultReply_t);
2753 memset(&reply_buf, 0, reply_sz);
2755 req_sz = sizeof(PortEnable_t);
2756 memset(&port_enable, 0, req_sz);
2758 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2759 port_enable.PortNumber = portnum;
2760 /* port_enable.ChainOffset = 0; */
2761 /* port_enable.MsgFlags = 0; */
2762 /* port_enable.MsgContext = 0; */
2764 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2765 ioc->name, portnum, &port_enable));
2767 /* RAID FW may take a long time to enable
2769 if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2770 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
2771 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2772 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2774 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2775 reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
2781 * ioc: Pointer to MPT_ADAPTER structure
2782 * size - total FW bytes
2785 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2788 return; /* use already allocated memory */
2789 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2790 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2791 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2793 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2794 ioc->alloc_total += size;
2798 * If alt_img is NULL, delete from ioc structure.
2799 * Else, delete a secondary image in same format.
2802 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2806 sz = ioc->facts.FWImageSize;
2807 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2808 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2809 pci_free_consistent(ioc->pcidev, sz,
2810 ioc->cached_fw, ioc->cached_fw_dma);
2811 ioc->cached_fw = NULL;
2817 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2819 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2820 * @ioc: Pointer to MPT_ADAPTER structure
2821 * @sleepFlag: Specifies whether the process can sleep
2823 * Returns 0 for success, >0 for handshake failure
2824 * <0 for fw upload failure.
2826 * Remark: If bound IOC and a successful FWUpload was performed
2827 * on the bound IOC, the second image is discarded
2828 * and memory is free'd. Both channels must upload to prevent
2829 * IOC from running in degraded mode.
2832 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2834 u8 request[ioc->req_sz];
2835 u8 reply[sizeof(FWUploadReply_t)];
2836 FWUpload_t *prequest;
2837 FWUploadReply_t *preply;
2838 FWUploadTCSGE_t *ptcsge;
2841 int ii, sz, reply_sz;
2844 /* If the image size is 0, we are done.
2846 if ((sz = ioc->facts.FWImageSize) == 0)
2849 mpt_alloc_fw_memory(ioc, sz);
2851 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2852 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2854 if (ioc->cached_fw == NULL) {
2860 prequest = (FWUpload_t *)&request;
2861 preply = (FWUploadReply_t *)&reply;
2863 /* Destination... */
2864 memset(prequest, 0, ioc->req_sz);
2866 reply_sz = sizeof(reply);
2867 memset(preply, 0, reply_sz);
2869 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2870 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2872 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2873 ptcsge->DetailsLength = 12;
2874 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2875 ptcsge->ImageSize = cpu_to_le32(sz);
2877 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2879 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2880 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2882 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2883 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2884 prequest, sgeoffset));
2885 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2887 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2888 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2890 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2892 cmdStatus = -EFAULT;
2894 /* Handshake transfer was complete and successful.
2895 * Check the Reply Frame.
2897 int status, transfer_sz;
2898 status = le16_to_cpu(preply->IOCStatus);
2899 if (status == MPI_IOCSTATUS_SUCCESS) {
2900 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2901 if (transfer_sz == sz)
2905 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2906 ioc->name, cmdStatus));
2911 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2913 mpt_free_fw_memory(ioc);
2919 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2921 * mpt_downloadboot - DownloadBoot code
2922 * @ioc: Pointer to MPT_ADAPTER structure
2923 * @flag: Specify which part of IOC memory is to be uploaded.
2924 * @sleepFlag: Specifies whether the process can sleep
2926 * FwDownloadBoot requires Programmed IO access.
2928 * Returns 0 for success
2929 * -1 FW Image size is 0
2930 * -2 No valid cached_fw Pointer
2931 * <0 for fw upload failure.
2934 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2936 MpiExtImageHeader_t *pExtImage;
2946 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2947 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2949 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2950 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2951 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2952 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2953 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2954 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2956 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2959 if (sleepFlag == CAN_SLEEP) {
2960 msleep_interruptible(1);
2965 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2966 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2968 for (count = 0; count < 30; count ++) {
2969 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2970 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2971 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2976 if (sleepFlag == CAN_SLEEP) {
2977 msleep_interruptible (100);
2983 if ( count == 30 ) {
2984 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2985 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2986 ioc->name, diag0val));
2990 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2991 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2992 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2993 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2994 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2995 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2997 /* Set the DiagRwEn and Disable ARM bits */
2998 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3000 fwSize = (pFwHeader->ImageSize + 3)/4;
3001 ptrFw = (u32 *) pFwHeader;
3003 /* Write the LoadStartAddress to the DiagRw Address Register
3004 * using Programmed IO
3006 if (ioc->errata_flag_1064)
3007 pci_enable_io_access(ioc->pcidev);
3009 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3010 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
3011 ioc->name, pFwHeader->LoadStartAddress));
3013 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
3014 ioc->name, fwSize*4, ptrFw));
3016 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3019 nextImage = pFwHeader->NextImageHeaderOffset;
3021 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3023 load_addr = pExtImage->LoadStartAddress;
3025 fwSize = (pExtImage->ImageSize + 3) >> 2;
3026 ptrFw = (u32 *)pExtImage;
3028 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3029 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3030 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3033 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3035 nextImage = pExtImage->NextImageHeaderOffset;
3038 /* Write the IopResetVectorRegAddr */
3039 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3040 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3042 /* Write the IopResetVectorValue */
3043 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3044 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3046 /* Clear the internal flash bad bit - autoincrementing register,
3047 * so must do two writes.
3049 if (ioc->bus_type == SPI) {
3051 * 1030 and 1035 H/W errata, workaround to access
3052 * the ClearFlashBadSignatureBit
3054 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3055 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3056 diagRwData |= 0x40000000;
3057 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3058 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3060 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3061 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3062 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3063 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3066 if (sleepFlag == CAN_SLEEP) {
3067 msleep_interruptible (1);
3073 if (ioc->errata_flag_1064)
3074 pci_disable_io_access(ioc->pcidev);
3076 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3077 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3078 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3079 ioc->name, diag0val));
3080 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3081 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3082 ioc->name, diag0val));
3083 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3085 /* Write 0xFF to reset the sequencer */
3086 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3088 if (ioc->bus_type == SAS) {
3089 ioc_state = mpt_GetIocState(ioc, 0);
3090 if ( (GetIocFacts(ioc, sleepFlag,
3091 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3092 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3093 ioc->name, ioc_state));
3098 for (count=0; count<HZ*20; count++) {
3099 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3100 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3101 ioc->name, count, ioc_state));
3102 if (ioc->bus_type == SAS) {
3105 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3106 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3110 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3114 if (sleepFlag == CAN_SLEEP) {
3115 msleep_interruptible (10);
3120 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3121 ioc->name, ioc_state));
3125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3127 * KickStart - Perform hard reset of MPT adapter.
3128 * @ioc: Pointer to MPT_ADAPTER structure
3129 * @force: Force hard reset
3130 * @sleepFlag: Specifies whether the process can sleep
3132 * This routine places MPT adapter in diagnostic mode via the
3133 * WriteSequence register, and then performs a hard reset of adapter
3134 * via the Diagnostic register.
3136 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3137 * or NO_SLEEP (interrupt thread, use mdelay)
3138 * force - 1 if doorbell active, board fault state
3139 * board operational, IOC_RECOVERY or
3140 * IOC_BRINGUP and there is an alt_ioc.
3144 * 1 - hard reset, READY
3145 * 0 - no reset due to History bit, READY
3146 * -1 - no reset due to History bit but not READY
3147 * OR reset but failed to come READY
3148 * -2 - no reset, could not enter DIAG mode
3149 * -3 - reset but bad FW bit
3152 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3154 int hard_reset_done = 0;
3158 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3159 if (ioc->bus_type == SPI) {
3160 /* Always issue a Msg Unit Reset first. This will clear some
3161 * SCSI bus hang conditions.
3163 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3165 if (sleepFlag == CAN_SLEEP) {
3166 msleep_interruptible (1000);
3172 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3173 if (hard_reset_done < 0)
3174 return hard_reset_done;
3176 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3179 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3180 for (cnt=0; cnt<cntdn; cnt++) {
3181 ioc_state = mpt_GetIocState(ioc, 1);
3182 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3183 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3185 return hard_reset_done;
3187 if (sleepFlag == CAN_SLEEP) {
3188 msleep_interruptible (10);
3194 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3195 ioc->name, ioc_state);
3199 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3201 * mpt_diag_reset - Perform hard reset of the adapter.
3202 * @ioc: Pointer to MPT_ADAPTER structure
3203 * @ignore: Set if to honor and clear to ignore
3204 * the reset history bit
3205 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3206 * else set to NO_SLEEP (use mdelay instead)
3208 * This routine places the adapter in diagnostic mode via the
3209 * WriteSequence register and then performs a hard reset of adapter
3210 * via the Diagnostic register. Adapter should be in ready state
3211 * upon successful completion.
3213 * Returns: 1 hard reset successful
3214 * 0 no reset performed because reset history bit set
3215 * -2 enabling diagnostic mode failed
3216 * -3 diagnostic reset failed
3219 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3223 int hard_reset_done = 0;
3229 /* Clear any existing interrupts */
3230 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3232 /* Use "Diagnostic reset" method! (only thing available!) */
3233 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3237 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3238 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3239 ioc->name, diag0val, diag1val));
3242 /* Do the reset if we are told to ignore the reset history
3243 * or if the reset history is 0
3245 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3246 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3247 /* Write magic sequence to WriteSequence register
3248 * Loop until in diagnostic mode
3250 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3251 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3252 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3253 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3254 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3255 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3258 if (sleepFlag == CAN_SLEEP) {
3259 msleep_interruptible (100);
3266 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3267 ioc->name, diag0val);
3272 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3274 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3275 ioc->name, diag0val));
3280 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3281 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3282 ioc->name, diag0val, diag1val));
3285 * Disable the ARM (Bug fix)
3288 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3292 * Now hit the reset bit in the Diagnostic register
3293 * (THE BIG HAMMER!) (Clears DRWE bit).
3295 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3296 hard_reset_done = 1;
3297 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3301 * Call each currently registered protocol IOC reset handler
3302 * with pre-reset indication.
3303 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3304 * MptResetHandlers[] registered yet.
3310 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3311 if (MptResetHandlers[ii]) {
3312 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3314 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3316 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3317 ioc->name, ioc->alt_ioc->name, ii));
3318 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3322 /* FIXME? Examine results here? */
3325 if (ioc->cached_fw) {
3326 /* If the DownloadBoot operation fails, the
3327 * IOC will be left unusable. This is a fatal error
3328 * case. _diag_reset will return < 0
3330 for (count = 0; count < 30; count ++) {
3331 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3332 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3337 if (sleepFlag == CAN_SLEEP) {
3338 msleep_interruptible (1000);
3343 if ((count = mpt_downloadboot(ioc,
3344 (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
3345 printk(KERN_WARNING MYNAM
3346 ": firmware downloadboot failure (%d)!\n", count);
3350 /* Wait for FW to reload and for board
3351 * to go to the READY state.
3352 * Maximum wait is 60 seconds.
3353 * If fail, no error will check again
3354 * with calling program.
3356 for (count = 0; count < 60; count ++) {
3357 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3358 doorbell &= MPI_IOC_STATE_MASK;
3360 if (doorbell == MPI_IOC_STATE_READY) {
3365 if (sleepFlag == CAN_SLEEP) {
3366 msleep_interruptible (1000);
3374 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3377 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3378 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3379 ioc->name, diag0val, diag1val));
3382 /* Clear RESET_HISTORY bit! Place board in the
3383 * diagnostic mode to update the diag register.
3385 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3387 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3388 /* Write magic sequence to WriteSequence register
3389 * Loop until in diagnostic mode
3391 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3392 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3393 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3394 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3395 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3396 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3399 if (sleepFlag == CAN_SLEEP) {
3400 msleep_interruptible (100);
3407 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3408 ioc->name, diag0val);
3411 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3413 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3414 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3415 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3416 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3417 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3421 /* Disable Diagnostic Mode
3423 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3425 /* Check FW reload status flags.
3427 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3428 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3429 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3430 ioc->name, diag0val);
3436 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3437 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3438 ioc->name, diag0val, diag1val));
3442 * Reset flag that says we've enabled event notification
3444 ioc->facts.EventState = 0;
3447 ioc->alt_ioc->facts.EventState = 0;
3449 return hard_reset_done;
3452 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3454 * SendIocReset - Send IOCReset request to MPT adapter.
3455 * @ioc: Pointer to MPT_ADAPTER structure
3456 * @reset_type: reset type, expected values are
3457 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3459 * Send IOCReset request to the MPT adapter.
3461 * Returns 0 for success, non-zero for failure.
3464 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3470 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3471 ioc->name, reset_type));
3472 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3473 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3476 /* FW ACK'd request, wait for READY state
3479 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3481 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3485 if (sleepFlag != CAN_SLEEP)
3488 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3489 ioc->name, (int)((count+5)/HZ));
3493 if (sleepFlag == CAN_SLEEP) {
3494 msleep_interruptible(1);
3496 mdelay (1); /* 1 msec delay */
3501 * Cleanup all event stuff for this IOC; re-issue EventNotification
3502 * request if needed.
3504 if (ioc->facts.Function)
3505 ioc->facts.EventState = 0;
3510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3512 * initChainBuffers - Allocate memory for and initialize
3513 * chain buffers, chain buffer control arrays and spinlock.
3514 * @hd: Pointer to MPT_SCSI_HOST structure
3515 * @init: If set, initialize the spin lock.
3518 initChainBuffers(MPT_ADAPTER *ioc)
3521 int sz, ii, num_chain;
3522 int scale, num_sge, numSGE;
3524 /* ReqToChain size must equal the req_depth
3527 if (ioc->ReqToChain == NULL) {
3528 sz = ioc->req_depth * sizeof(int);
3529 mem = kmalloc(sz, GFP_ATOMIC);
3533 ioc->ReqToChain = (int *) mem;
3534 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3535 ioc->name, mem, sz));
3536 mem = kmalloc(sz, GFP_ATOMIC);
3540 ioc->RequestNB = (int *) mem;
3541 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3542 ioc->name, mem, sz));
3544 for (ii = 0; ii < ioc->req_depth; ii++) {
3545 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3548 /* ChainToChain size must equal the total number
3549 * of chain buffers to be allocated.
3552 * Calculate the number of chain buffers needed(plus 1) per I/O
3553 * then multiply the the maximum number of simultaneous cmds
3555 * num_sge = num sge in request frame + last chain buffer
3556 * scale = num sge per chain buffer if no chain element
3558 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3559 if (sizeof(dma_addr_t) == sizeof(u64))
3560 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3562 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3564 if (sizeof(dma_addr_t) == sizeof(u64)) {
3565 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3566 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3568 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3569 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3571 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3572 ioc->name, num_sge, numSGE));
3574 if ( numSGE > MPT_SCSI_SG_DEPTH )
3575 numSGE = MPT_SCSI_SG_DEPTH;
3578 while (numSGE - num_sge > 0) {
3580 num_sge += (scale - 1);
3584 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3585 ioc->name, numSGE, num_sge, num_chain));
3587 if (ioc->bus_type == SPI)
3588 num_chain *= MPT_SCSI_CAN_QUEUE;
3590 num_chain *= MPT_FC_CAN_QUEUE;
3592 ioc->num_chain = num_chain;
3594 sz = num_chain * sizeof(int);
3595 if (ioc->ChainToChain == NULL) {
3596 mem = kmalloc(sz, GFP_ATOMIC);
3600 ioc->ChainToChain = (int *) mem;
3601 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3602 ioc->name, mem, sz));
3604 mem = (u8 *) ioc->ChainToChain;
3606 memset(mem, 0xFF, sz);
3610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3612 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3613 * @ioc: Pointer to MPT_ADAPTER structure
3615 * This routine allocates memory for the MPT reply and request frame
3616 * pools (if necessary), and primes the IOC reply FIFO with
3619 * Returns 0 for success, non-zero for failure.
3622 PrimeIocFifos(MPT_ADAPTER *ioc)
3625 unsigned long flags;
3626 dma_addr_t alloc_dma;
3628 int i, reply_sz, sz, total_size, num_chain;
3630 /* Prime reply FIFO... */
3632 if (ioc->reply_frames == NULL) {
3633 if ( (num_chain = initChainBuffers(ioc)) < 0)
3636 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3637 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3638 ioc->name, ioc->reply_sz, ioc->reply_depth));
3639 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3640 ioc->name, reply_sz, reply_sz));
3642 sz = (ioc->req_sz * ioc->req_depth);
3643 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3644 ioc->name, ioc->req_sz, ioc->req_depth));
3645 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3646 ioc->name, sz, sz));
3649 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3650 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3651 ioc->name, ioc->req_sz, num_chain));
3652 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3653 ioc->name, sz, sz, num_chain));
3656 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3658 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3663 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3664 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3666 memset(mem, 0, total_size);
3667 ioc->alloc_total += total_size;
3669 ioc->alloc_dma = alloc_dma;
3670 ioc->alloc_sz = total_size;
3671 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3672 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3674 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3675 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3677 alloc_dma += reply_sz;
3680 /* Request FIFO - WE manage this! */
3682 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3683 ioc->req_frames_dma = alloc_dma;
3685 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3686 ioc->name, mem, (void *)(ulong)alloc_dma));
3688 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3690 #if defined(CONFIG_MTRR) && 0
3692 * Enable Write Combining MTRR for IOC's memory region.
3693 * (at least as much as we can; "size and base must be
3694 * multiples of 4 kiB"
3696 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3698 MTRR_TYPE_WRCOMB, 1);
3699 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3700 ioc->name, ioc->req_frames_dma, sz));
3703 for (i = 0; i < ioc->req_depth; i++) {
3704 alloc_dma += ioc->req_sz;
3708 ioc->ChainBuffer = mem;
3709 ioc->ChainBufferDMA = alloc_dma;
3711 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3712 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3714 /* Initialize the free chain Q.
3717 INIT_LIST_HEAD(&ioc->FreeChainQ);
3719 /* Post the chain buffers to the FreeChainQ.
3721 mem = (u8 *)ioc->ChainBuffer;
3722 for (i=0; i < num_chain; i++) {
3723 mf = (MPT_FRAME_HDR *) mem;
3724 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3728 /* Initialize Request frames linked list
3730 alloc_dma = ioc->req_frames_dma;
3731 mem = (u8 *) ioc->req_frames;
3733 spin_lock_irqsave(&ioc->FreeQlock, flags);
3734 INIT_LIST_HEAD(&ioc->FreeQ);
3735 for (i = 0; i < ioc->req_depth; i++) {
3736 mf = (MPT_FRAME_HDR *) mem;
3738 /* Queue REQUESTs *internally*! */
3739 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3743 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3745 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3746 ioc->sense_buf_pool =
3747 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3748 if (ioc->sense_buf_pool == NULL) {
3749 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3754 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3755 ioc->alloc_total += sz;
3756 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3757 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3761 /* Post Reply frames to FIFO
3763 alloc_dma = ioc->alloc_dma;
3764 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3765 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3767 for (i = 0; i < ioc->reply_depth; i++) {
3768 /* Write each address to the IOC! */
3769 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3770 alloc_dma += ioc->reply_sz;
3776 if (ioc->alloc != NULL) {
3778 pci_free_consistent(ioc->pcidev,
3780 ioc->alloc, ioc->alloc_dma);
3781 ioc->reply_frames = NULL;
3782 ioc->req_frames = NULL;
3783 ioc->alloc_total -= sz;
3785 if (ioc->sense_buf_pool != NULL) {
3786 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3787 pci_free_consistent(ioc->pcidev,
3789 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3790 ioc->sense_buf_pool = NULL;
3795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3797 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3798 * from IOC via doorbell handshake method.
3799 * @ioc: Pointer to MPT_ADAPTER structure
3800 * @reqBytes: Size of the request in bytes
3801 * @req: Pointer to MPT request frame
3802 * @replyBytes: Expected size of the reply in bytes
3803 * @u16reply: Pointer to area where reply should be written
3804 * @maxwait: Max wait time for a reply (in seconds)
3805 * @sleepFlag: Specifies whether the process can sleep
3807 * NOTES: It is the callers responsibility to byte-swap fields in the
3808 * request which are greater than 1 byte in size. It is also the
3809 * callers responsibility to byte-swap response fields which are
3810 * greater than 1 byte in size.
3812 * Returns 0 for success, non-zero for failure.
3815 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3816 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3818 MPIDefaultReply_t *mptReply;
3823 * Get ready to cache a handshake reply
3825 ioc->hs_reply_idx = 0;
3826 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3827 mptReply->MsgLength = 0;
3830 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3831 * then tell IOC that we want to handshake a request of N words.
3832 * (WRITE u32val to Doorbell reg).
3834 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3835 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3836 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3837 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3840 * Wait for IOC's doorbell handshake int
3842 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3845 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3846 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3848 /* Read doorbell and check for active bit */
3849 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3853 * Clear doorbell int (WRITE 0 to IntStatus reg),
3854 * then wait for IOC to ACKnowledge that it's ready for
3855 * our handshake request.
3857 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3858 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3863 u8 *req_as_bytes = (u8 *) req;
3866 * Stuff request words via doorbell handshake,
3867 * with ACK from IOC for each.
3869 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3870 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3871 (req_as_bytes[(ii*4) + 1] << 8) |
3872 (req_as_bytes[(ii*4) + 2] << 16) |
3873 (req_as_bytes[(ii*4) + 3] << 24));
3875 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3876 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3880 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3881 DBG_DUMP_REQUEST_FRAME_HDR(req)
3883 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3884 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3887 * Wait for completion of doorbell handshake reply from the IOC
3889 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3892 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3893 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3896 * Copy out the cached reply...
3898 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3899 u16reply[ii] = ioc->hs_reply[ii];
3907 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3909 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3910 * in it's IntStatus register.
3911 * @ioc: Pointer to MPT_ADAPTER structure
3912 * @howlong: How long to wait (in seconds)
3913 * @sleepFlag: Specifies whether the process can sleep
3915 * This routine waits (up to ~2 seconds max) for IOC doorbell
3916 * handshake ACKnowledge.
3918 * Returns a negative value on failure, else wait loop count.
3921 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3927 cntdn = 1000 * howlong;
3929 if (sleepFlag == CAN_SLEEP) {
3931 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3932 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3934 msleep_interruptible (1);
3939 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3940 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3948 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3953 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3954 ioc->name, count, intstat);
3958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3960 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3961 * in it's IntStatus register.
3962 * @ioc: Pointer to MPT_ADAPTER structure
3963 * @howlong: How long to wait (in seconds)
3964 * @sleepFlag: Specifies whether the process can sleep
3966 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3968 * Returns a negative value on failure, else wait loop count.
3971 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3977 cntdn = 1000 * howlong;
3978 if (sleepFlag == CAN_SLEEP) {
3980 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3981 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3983 msleep_interruptible(1);
3988 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3989 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3997 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3998 ioc->name, count, howlong));
4002 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4003 ioc->name, count, intstat);
4007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4009 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
4010 * @ioc: Pointer to MPT_ADAPTER structure
4011 * @howlong: How long to wait (in seconds)
4012 * @sleepFlag: Specifies whether the process can sleep
4014 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4015 * Reply is cached to IOC private area large enough to hold a maximum
4016 * of 128 bytes of reply data.
4018 * Returns a negative value on failure, else size of reply in WORDS.
4021 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4026 u16 *hs_reply = ioc->hs_reply;
4027 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4030 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4033 * Get first two u16's so we can look at IOC's intended reply MsgLength
4036 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4039 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4040 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4041 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4044 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4045 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4049 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4050 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4051 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4054 * If no error (and IOC said MsgLength is > 0), piece together
4055 * reply 16 bits at a time.
4057 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4058 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4060 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4061 /* don't overflow our IOC hs_reply[] buffer! */
4062 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4063 hs_reply[u16cnt] = hword;
4064 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4067 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4069 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4072 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4077 else if (u16cnt != (2 * mptReply->MsgLength)) {
4080 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4085 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4086 DBG_DUMP_REPLY_FRAME(mptReply)
4088 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4089 ioc->name, t, u16cnt/2));
4093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4095 * GetLanConfigPages - Fetch LANConfig pages.
4096 * @ioc: Pointer to MPT_ADAPTER structure
4098 * Return: 0 for success
4099 * -ENOMEM if no memory available
4100 * -EPERM if not allowed due to ISR context
4101 * -EAGAIN if no msg frames currently available
4102 * -EFAULT for non-successful reply or no reply (timeout)
4105 GetLanConfigPages(MPT_ADAPTER *ioc)
4107 ConfigPageHeader_t hdr;
4109 LANPage0_t *ppage0_alloc;
4110 dma_addr_t page0_dma;
4111 LANPage1_t *ppage1_alloc;
4112 dma_addr_t page1_dma;
4117 /* Get LAN Page 0 header */
4118 hdr.PageVersion = 0;
4121 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4122 cfg.cfghdr.hdr = &hdr;
4124 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4129 if ((rc = mpt_config(ioc, &cfg)) != 0)
4132 if (hdr.PageLength > 0) {
4133 data_sz = hdr.PageLength * 4;
4134 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4137 memset((u8 *)ppage0_alloc, 0, data_sz);
4138 cfg.physAddr = page0_dma;
4139 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4141 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4143 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4144 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4148 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4151 * Normalize endianness of structure data,
4152 * by byte-swapping all > 1 byte fields!
4161 /* Get LAN Page 1 header */
4162 hdr.PageVersion = 0;
4165 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4166 cfg.cfghdr.hdr = &hdr;
4168 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4172 if ((rc = mpt_config(ioc, &cfg)) != 0)
4175 if (hdr.PageLength == 0)
4178 data_sz = hdr.PageLength * 4;
4180 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4182 memset((u8 *)ppage1_alloc, 0, data_sz);
4183 cfg.physAddr = page1_dma;
4184 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4186 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4188 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4189 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4192 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4195 * Normalize endianness of structure data,
4196 * by byte-swapping all > 1 byte fields!
4204 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4206 * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
4207 * @ioc: Pointer to MPT_ADAPTER structure
4208 * @portnum: IOC Port number
4210 * Return: 0 for success
4211 * -ENOMEM if no memory available
4212 * -EPERM if not allowed due to ISR context
4213 * -EAGAIN if no msg frames currently available
4214 * -EFAULT for non-successful reply or no reply (timeout)
4217 mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4219 ConfigPageHeader_t hdr;
4221 FCPortPage0_t *ppage0_alloc;
4222 FCPortPage0_t *pp0dest;
4223 dma_addr_t page0_dma;
4230 /* Get FCPort Page 0 header */
4231 hdr.PageVersion = 0;
4234 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4235 cfg.cfghdr.hdr = &hdr;
4237 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4239 cfg.pageAddr = portnum;
4242 if ((rc = mpt_config(ioc, &cfg)) != 0)
4245 if (hdr.PageLength == 0)
4248 data_sz = hdr.PageLength * 4;
4250 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4254 memset((u8 *)ppage0_alloc, 0, data_sz);
4255 cfg.physAddr = page0_dma;
4256 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4258 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4260 pp0dest = &ioc->fc_port_page0[portnum];
4261 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4262 memcpy(pp0dest, ppage0_alloc, copy_sz);
4265 * Normalize endianness of structure data,
4266 * by byte-swapping all > 1 byte fields!
4268 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4269 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4270 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4271 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4272 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4273 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4274 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4275 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4276 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4277 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4278 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4279 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4280 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4281 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4282 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4283 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4286 * if still doing discovery,
4287 * hang loose a while until finished
4289 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
4291 msleep_interruptible(100);
4294 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
4300 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4306 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4308 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4309 * @ioc: Pointer to MPT_ADAPTER structure
4310 * @sas_address: 64bit SAS Address for operation.
4311 * @target_id: specified target for operation
4312 * @bus: specified bus for operation
4313 * @persist_opcode: see below
4315 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4316 * devices not currently present.
4317 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4319 * NOTE: Don't use not this function during interrupt time.
4321 * Returns: 0 for success, non-zero error
4324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4326 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4328 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4329 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4330 MPT_FRAME_HDR *mf = NULL;
4331 MPIHeader_t *mpi_hdr;
4334 /* insure garbage is not sent to fw */
4335 switch(persist_opcode) {
4337 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4338 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4346 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4348 /* Get a MF for this command.
4350 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4351 printk("%s: no msg frames!\n",__FUNCTION__);
4355 mpi_hdr = (MPIHeader_t *) mf;
4356 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4357 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4358 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4359 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4360 sasIoUnitCntrReq->Operation = persist_opcode;
4362 init_timer(&ioc->persist_timer);
4363 ioc->persist_timer.data = (unsigned long) ioc;
4364 ioc->persist_timer.function = mpt_timer_expired;
4365 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4366 ioc->persist_wait_done=0;
4367 add_timer(&ioc->persist_timer);
4368 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4369 wait_event(mpt_waitq, ioc->persist_wait_done);
4371 sasIoUnitCntrReply =
4372 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4373 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4374 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4376 sasIoUnitCntrReply->IOCStatus,
4377 sasIoUnitCntrReply->IOCLogInfo);
4381 printk("%s: success\n",__FUNCTION__);
4385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4387 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4388 * @ioc: Pointer to MPT_ADAPTER structure
4390 * Returns: 0 for success
4391 * -ENOMEM if no memory available
4392 * -EPERM if not allowed due to ISR context
4393 * -EAGAIN if no msg frames currently available
4394 * -EFAULT for non-successful reply or no reply (timeout)
4397 GetIoUnitPage2(MPT_ADAPTER *ioc)
4399 ConfigPageHeader_t hdr;
4401 IOUnitPage2_t *ppage_alloc;
4402 dma_addr_t page_dma;
4406 /* Get the page header */
4407 hdr.PageVersion = 0;
4410 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4411 cfg.cfghdr.hdr = &hdr;
4413 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4418 if ((rc = mpt_config(ioc, &cfg)) != 0)
4421 if (hdr.PageLength == 0)
4424 /* Read the config page */
4425 data_sz = hdr.PageLength * 4;
4427 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4429 memset((u8 *)ppage_alloc, 0, data_sz);
4430 cfg.physAddr = page_dma;
4431 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4433 /* If Good, save data */
4434 if ((rc = mpt_config(ioc, &cfg)) == 0)
4435 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4437 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4443 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4444 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4445 * @ioc: Pointer to a Adapter Strucutre
4446 * @portnum: IOC port number
4448 * Return: -EFAULT if read of config page header fails
4450 * If read of SCSI Port Page 0 fails,
4451 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4452 * Adapter settings: async, narrow
4454 * If read of SCSI Port Page 2 fails,
4455 * Adapter settings valid
4456 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4461 * CHECK - what type of locking mechanisms should be used????
4464 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4469 ConfigPageHeader_t header;
4475 if (!ioc->spi_data.nvram) {
4478 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4479 mem = kmalloc(sz, GFP_ATOMIC);
4483 ioc->spi_data.nvram = (int *) mem;
4485 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4486 ioc->name, ioc->spi_data.nvram, sz));
4489 /* Invalidate NVRAM information
4491 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4492 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4495 /* Read SPP0 header, allocate memory, then read page.
4497 header.PageVersion = 0;
4498 header.PageLength = 0;
4499 header.PageNumber = 0;
4500 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4501 cfg.cfghdr.hdr = &header;
4503 cfg.pageAddr = portnum;
4504 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4506 cfg.timeout = 0; /* use default */
4507 if (mpt_config(ioc, &cfg) != 0)
4510 if (header.PageLength > 0) {
4511 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4513 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4514 cfg.physAddr = buf_dma;
4515 if (mpt_config(ioc, &cfg) != 0) {
4516 ioc->spi_data.maxBusWidth = MPT_NARROW;
4517 ioc->spi_data.maxSyncOffset = 0;
4518 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4519 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4521 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4522 ioc->name, ioc->spi_data.minSyncFactor));
4524 /* Save the Port Page 0 data
4526 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4527 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4528 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4530 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4531 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4532 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4533 ioc->name, pPP0->Capabilities));
4535 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4536 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4538 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4539 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4540 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4541 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4542 ioc->name, ioc->spi_data.minSyncFactor));
4544 ioc->spi_data.maxSyncOffset = 0;
4545 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4548 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4550 /* Update the minSyncFactor based on bus type.
4552 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4553 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4555 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4556 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4557 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4558 ioc->name, ioc->spi_data.minSyncFactor));
4563 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4568 /* SCSI Port Page 2 - Read the header then the page.
4570 header.PageVersion = 0;
4571 header.PageLength = 0;
4572 header.PageNumber = 2;
4573 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4574 cfg.cfghdr.hdr = &header;
4576 cfg.pageAddr = portnum;
4577 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4579 if (mpt_config(ioc, &cfg) != 0)
4582 if (header.PageLength > 0) {
4583 /* Allocate memory and read SCSI Port Page 2
4585 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4587 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4588 cfg.physAddr = buf_dma;
4589 if (mpt_config(ioc, &cfg) != 0) {
4590 /* Nvram data is left with INVALID mark
4594 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4595 MpiDeviceInfo_t *pdevice = NULL;
4597 /* Save the Port Page 2 data
4598 * (reformat into a 32bit quantity)
4600 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4601 ioc->spi_data.PortFlags = data;
4602 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4603 pdevice = &pPP2->DeviceSettings[ii];
4604 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4605 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4606 ioc->spi_data.nvram[ii] = data;
4610 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4614 /* Update Adapter limits with those from NVRAM
4615 * Comment: Don't need to do this. Target performance
4616 * parameters will never exceed the adapters limits.
4622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4623 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4624 * @ioc: Pointer to a Adapter Strucutre
4625 * @portnum: IOC port number
4627 * Return: -EFAULT if read of config page header fails
4631 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4634 ConfigPageHeader_t header;
4636 /* Read the SCSI Device Page 1 header
4638 header.PageVersion = 0;
4639 header.PageLength = 0;
4640 header.PageNumber = 1;
4641 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4642 cfg.cfghdr.hdr = &header;
4644 cfg.pageAddr = portnum;
4645 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4648 if (mpt_config(ioc, &cfg) != 0)
4651 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4652 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4654 header.PageVersion = 0;
4655 header.PageLength = 0;
4656 header.PageNumber = 0;
4657 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4658 if (mpt_config(ioc, &cfg) != 0)
4661 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4662 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4664 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4665 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4667 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4668 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4674 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4675 * @ioc: Pointer to a Adapter Strucutre
4676 * @portnum: IOC port number
4680 * -EFAULT if read of config page header fails or data pointer not NULL
4681 * -ENOMEM if pci_alloc failed
4684 mpt_findImVolumes(MPT_ADAPTER *ioc)
4688 ConfigPageIoc2RaidVol_t *pIocRv;
4689 dma_addr_t ioc2_dma;
4691 ConfigPageHeader_t header;
4698 /* Read IOCP2 header then the page.
4700 header.PageVersion = 0;
4701 header.PageLength = 0;
4702 header.PageNumber = 2;
4703 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4704 cfg.cfghdr.hdr = &header;
4707 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4710 if (mpt_config(ioc, &cfg) != 0)
4713 if (header.PageLength == 0)
4716 iocpage2sz = header.PageLength * 4;
4717 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4721 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4722 cfg.physAddr = ioc2_dma;
4723 if (mpt_config(ioc, &cfg) != 0)
4726 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4727 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4729 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4734 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4736 /* Identify RAID Volume Id's */
4737 nVols = pIoc2->NumActiveVolumes;
4743 /* At least 1 RAID Volume
4745 pIocRv = pIoc2->RaidVolume;
4746 ioc->raid_data.isRaid = 0;
4747 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4748 vid = pIocRv->VolumeID;
4749 vbus = pIocRv->VolumeBus;
4750 vioc = pIocRv->VolumeIOC;
4755 ioc->raid_data.isRaid |= (1 << vid);
4757 /* Error! Always bus 0
4763 /* Identify Hidden Physical Disk Id's */
4764 nPhys = pIoc2->NumActivePhysDisks;
4766 /* No physical disks.
4769 mpt_read_ioc_pg_3(ioc);
4773 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4779 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4784 ConfigPageHeader_t header;
4785 dma_addr_t ioc3_dma;
4788 /* Free the old page
4790 kfree(ioc->raid_data.pIocPg3);
4791 ioc->raid_data.pIocPg3 = NULL;
4793 /* There is at least one physical disk.
4794 * Read and save IOC Page 3
4796 header.PageVersion = 0;
4797 header.PageLength = 0;
4798 header.PageNumber = 3;
4799 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4800 cfg.cfghdr.hdr = &header;
4803 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4806 if (mpt_config(ioc, &cfg) != 0)
4809 if (header.PageLength == 0)
4812 /* Read Header good, alloc memory
4814 iocpage3sz = header.PageLength * 4;
4815 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4819 /* Read the Page and save the data
4820 * into malloc'd memory.
4822 cfg.physAddr = ioc3_dma;
4823 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4824 if (mpt_config(ioc, &cfg) == 0) {
4825 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4827 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4828 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4832 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4838 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4842 ConfigPageHeader_t header;
4843 dma_addr_t ioc4_dma;
4846 /* Read and save IOC Page 4
4848 header.PageVersion = 0;
4849 header.PageLength = 0;
4850 header.PageNumber = 4;
4851 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4852 cfg.cfghdr.hdr = &header;
4855 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4858 if (mpt_config(ioc, &cfg) != 0)
4861 if (header.PageLength == 0)
4864 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4865 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4866 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4870 ioc4_dma = ioc->spi_data.IocPg4_dma;
4871 iocpage4sz = ioc->spi_data.IocPg4Sz;
4874 /* Read the Page into dma memory.
4876 cfg.physAddr = ioc4_dma;
4877 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4878 if (mpt_config(ioc, &cfg) == 0) {
4879 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4880 ioc->spi_data.IocPg4_dma = ioc4_dma;
4881 ioc->spi_data.IocPg4Sz = iocpage4sz;
4883 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4884 ioc->spi_data.pIocPg4 = NULL;
4889 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4893 ConfigPageHeader_t header;
4894 dma_addr_t ioc1_dma;
4898 /* Check the Coalescing Timeout in IOC Page 1
4900 header.PageVersion = 0;
4901 header.PageLength = 0;
4902 header.PageNumber = 1;
4903 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4904 cfg.cfghdr.hdr = &header;
4907 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4910 if (mpt_config(ioc, &cfg) != 0)
4913 if (header.PageLength == 0)
4916 /* Read Header good, alloc memory
4918 iocpage1sz = header.PageLength * 4;
4919 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4923 /* Read the Page and check coalescing timeout
4925 cfg.physAddr = ioc1_dma;
4926 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4927 if (mpt_config(ioc, &cfg) == 0) {
4929 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4930 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4931 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4933 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4936 if (tmp > MPT_COALESCING_TIMEOUT) {
4937 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4939 /* Write NVRAM and current
4942 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4943 if (mpt_config(ioc, &cfg) == 0) {
4944 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4945 ioc->name, MPT_COALESCING_TIMEOUT));
4947 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4948 if (mpt_config(ioc, &cfg) == 0) {
4949 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4950 ioc->name, MPT_COALESCING_TIMEOUT));
4952 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4957 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4963 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4967 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4972 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4974 * SendEventNotification - Send EventNotification (on or off) request
4976 * @ioc: Pointer to MPT_ADAPTER structure
4977 * @EvSwitch: Event switch flags
4980 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4982 EventNotification_t *evnp;
4984 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4986 devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4990 memset(evnp, 0, sizeof(*evnp));
4992 devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
4994 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4995 evnp->ChainOffset = 0;
4997 evnp->Switch = EvSwitch;
4999 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5004 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5006 * SendEventAck - Send EventAck request to MPT adapter.
5007 * @ioc: Pointer to MPT_ADAPTER structure
5008 * @evnp: Pointer to original EventNotification request
5011 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5015 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5016 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
5017 "request frame for Event=%x EventContext=%x EventData=%x!\n",
5018 ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
5019 le32_to_cpu(evnp->Data[0]));
5022 memset(pAck, 0, sizeof(*pAck));
5024 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5026 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5027 pAck->ChainOffset = 0;
5029 pAck->Event = evnp->Event;
5030 pAck->EventContext = evnp->EventContext;
5032 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5037 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5039 * mpt_config - Generic function to issue config message
5040 * @ioc - Pointer to an adapter structure
5041 * @cfg - Pointer to a configuration structure. Struct contains
5042 * action, page address, direction, physical address
5043 * and pointer to a configuration page header
5044 * Page header is updated.
5046 * Returns 0 for success
5047 * -EPERM if not allowed due to ISR context
5048 * -EAGAIN if no msg frames currently available
5049 * -EFAULT for non-successful reply or no reply (timeout)
5052 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5055 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5057 unsigned long flags;
5062 /* Prevent calling wait_event() (below), if caller happens
5063 * to be in ISR context, because that is fatal!
5065 in_isr = in_interrupt();
5067 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5072 /* Get and Populate a free Frame
5074 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5075 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5079 pReq = (Config_t *)mf;
5080 pReq->Action = pCfg->action;
5082 pReq->ChainOffset = 0;
5083 pReq->Function = MPI_FUNCTION_CONFIG;
5085 /* Assume page type is not extended and clear "reserved" fields. */
5086 pReq->ExtPageLength = 0;
5087 pReq->ExtPageType = 0;
5090 for (ii=0; ii < 8; ii++)
5091 pReq->Reserved2[ii] = 0;
5093 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5094 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5095 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5096 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5098 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5099 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5100 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5101 pReq->ExtPageType = pExtHdr->ExtPageType;
5102 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5104 /* Page Length must be treated as a reserved field for the extended header. */
5105 pReq->Header.PageLength = 0;
5108 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5110 /* Add a SGE to the config request.
5113 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5115 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5117 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5118 flagsLength |= pExtHdr->ExtPageLength * 4;
5120 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5121 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5124 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5126 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5127 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5130 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5132 /* Append pCfg pointer to end of mf
5134 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5136 /* Initalize the timer
5138 init_timer(&pCfg->timer);
5139 pCfg->timer.data = (unsigned long) ioc;
5140 pCfg->timer.function = mpt_timer_expired;
5141 pCfg->wait_done = 0;
5143 /* Set the timer; ensure 10 second minimum */
5144 if (pCfg->timeout < 10)
5145 pCfg->timer.expires = jiffies + HZ*10;
5147 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5149 /* Add to end of Q, set timer and then issue this command */
5150 spin_lock_irqsave(&ioc->FreeQlock, flags);
5151 list_add_tail(&pCfg->linkage, &ioc->configQ);
5152 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5154 add_timer(&pCfg->timer);
5155 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5156 wait_event(mpt_waitq, pCfg->wait_done);
5158 /* mf has been freed - do not access */
5165 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5167 * mpt_toolbox - Generic function to issue toolbox message
5168 * @ioc - Pointer to an adapter structure
5169 * @cfg - Pointer to a toolbox structure. Struct contains
5170 * action, page address, direction, physical address
5171 * and pointer to a configuration page header
5172 * Page header is updated.
5174 * Returns 0 for success
5175 * -EPERM if not allowed due to ISR context
5176 * -EAGAIN if no msg frames currently available
5177 * -EFAULT for non-successful reply or no reply (timeout)
5180 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5182 ToolboxIstwiReadWriteRequest_t *pReq;
5184 struct pci_dev *pdev;
5185 unsigned long flags;
5190 /* Prevent calling wait_event() (below), if caller happens
5191 * to be in ISR context, because that is fatal!
5193 in_isr = in_interrupt();
5195 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
5200 /* Get and Populate a free Frame
5202 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5203 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
5207 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
5208 pReq->Tool = pCfg->action;
5210 pReq->ChainOffset = 0;
5211 pReq->Function = MPI_FUNCTION_TOOLBOX;
5212 pReq->Reserved1 = 0;
5213 pReq->Reserved2 = 0;
5215 pReq->Flags = pCfg->dir;
5217 pReq->Reserved3 = 0;
5218 pReq->NumAddressBytes = 0x01;
5219 pReq->Reserved4 = 0;
5220 pReq->DataLength = cpu_to_le16(0x04);
5222 if (pdev->devfn & 1)
5223 pReq->DeviceAddr = 0xB2;
5225 pReq->DeviceAddr = 0xB0;
5229 pReq->Reserved5 = 0;
5231 /* Add a SGE to the config request.
5234 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
5236 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
5238 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
5239 ioc->name, pReq->Tool));
5241 /* Append pCfg pointer to end of mf
5243 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5245 /* Initalize the timer
5247 init_timer(&pCfg->timer);
5248 pCfg->timer.data = (unsigned long) ioc;
5249 pCfg->timer.function = mpt_timer_expired;
5250 pCfg->wait_done = 0;
5252 /* Set the timer; ensure 10 second minimum */
5253 if (pCfg->timeout < 10)
5254 pCfg->timer.expires = jiffies + HZ*10;
5256 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5258 /* Add to end of Q, set timer and then issue this command */
5259 spin_lock_irqsave(&ioc->FreeQlock, flags);
5260 list_add_tail(&pCfg->linkage, &ioc->configQ);
5261 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5263 add_timer(&pCfg->timer);
5264 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5265 wait_event(mpt_waitq, pCfg->wait_done);
5267 /* mf has been freed - do not access */
5274 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5276 * mpt_timer_expired - Call back for timer process.
5277 * Used only internal config functionality.
5278 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5281 mpt_timer_expired(unsigned long data)
5283 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5285 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5287 /* Perform a FW reload */
5288 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5289 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5291 /* No more processing.
5292 * Hard reset clean-up will wake up
5293 * process and free all resources.
5295 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5300 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5302 * mpt_ioc_reset - Base cleanup for hard reset
5303 * @ioc: Pointer to the adapter structure
5304 * @reset_phase: Indicates pre- or post-reset functionality
5306 * Remark: Free's resources with internally generated commands.
5309 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5312 unsigned long flags;
5314 dprintk((KERN_WARNING MYNAM
5315 ": IOC %s_reset routed to MPT base driver!\n",
5316 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5317 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5319 if (reset_phase == MPT_IOC_SETUP_RESET) {
5321 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5322 /* If the internal config Q is not empty -
5323 * delete timer. MF resources will be freed when
5324 * the FIFO's are primed.
5326 spin_lock_irqsave(&ioc->FreeQlock, flags);
5327 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5328 del_timer(&pCfg->timer);
5329 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5334 /* Search the configQ for internal commands.
5335 * Flush the Q, and wake up all suspended threads.
5337 spin_lock_irqsave(&ioc->FreeQlock, flags);
5338 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5339 list_del(&pCfg->linkage);
5341 pCfg->status = MPT_CONFIG_ERROR;
5342 pCfg->wait_done = 1;
5343 wake_up(&mpt_waitq);
5345 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5348 return 1; /* currently means nothing really */
5352 #ifdef CONFIG_PROC_FS /* { */
5353 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5355 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5359 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5361 * Returns 0 for success, non-zero for failure.
5364 procmpt_create(void)
5366 struct proc_dir_entry *ent;
5368 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5369 if (mpt_proc_root_dir == NULL)
5372 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5374 ent->read_proc = procmpt_summary_read;
5376 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5378 ent->read_proc = procmpt_version_read;
5383 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5385 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5387 * Returns 0 for success, non-zero for failure.
5390 procmpt_destroy(void)
5392 remove_proc_entry("version", mpt_proc_root_dir);
5393 remove_proc_entry("summary", mpt_proc_root_dir);
5394 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5397 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5399 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5400 * or from /proc/mpt/iocN/summary.
5401 * @buf: Pointer to area to write information
5402 * @start: Pointer to start pointer
5403 * @offset: Offset to start writing
5405 * @eof: Pointer to EOF integer
5408 * Returns number of characters written to process performing the read.
5411 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5421 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5425 list_for_each_entry(ioc, &ioc_list, list) {
5428 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5431 if ((out-buf) >= request)
5438 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5441 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5443 * procmpt_version_read - Handle read request from /proc/mpt/version.
5444 * @buf: Pointer to area to write information
5445 * @start: Pointer to start pointer
5446 * @offset: Offset to start writing
5448 * @eof: Pointer to EOF integer
5451 * Returns number of characters written to process performing the read.
5454 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5457 int scsi, fc, sas, lan, ctl, targ, dmp;
5461 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5462 len += sprintf(buf+len, " Fusion MPT base driver\n");
5464 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5465 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5467 if (MptCallbacks[ii]) {
5468 switch (MptDriverClass[ii]) {
5470 if (!scsi++) drvname = "SPI host";
5473 if (!fc++) drvname = "FC host";
5476 if (!sas++) drvname = "SAS host";
5479 if (!lan++) drvname = "LAN";
5482 if (!targ++) drvname = "SCSI target";
5485 if (!ctl++) drvname = "ioctl";
5490 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5494 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5497 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5499 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5500 * @buf: Pointer to area to write information
5501 * @start: Pointer to start pointer
5502 * @offset: Offset to start writing
5504 * @eof: Pointer to EOF integer
5507 * Returns number of characters written to process performing the read.
5510 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5512 MPT_ADAPTER *ioc = data;
5518 mpt_get_fw_exp_ver(expVer, ioc);
5520 len = sprintf(buf, "%s:", ioc->name);
5521 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5522 len += sprintf(buf+len, " (f/w download boot flag set)");
5523 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5524 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5526 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5527 ioc->facts.ProductID,
5529 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5530 if (ioc->facts.FWImageSize)
5531 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5532 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5533 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5534 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5536 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5537 ioc->facts.CurrentHostMfaHighAddr);
5538 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5539 ioc->facts.CurrentSenseBufferHighAddr);
5541 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5542 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5544 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5545 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5547 * Rounding UP to nearest 4-kB boundary here...
5549 sz = (ioc->req_sz * ioc->req_depth) + 128;
5550 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5551 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5552 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5553 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5554 4*ioc->facts.RequestFrameSize,
5555 ioc->facts.GlobalCredits);
5557 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5558 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5559 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5560 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5561 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5562 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5563 ioc->facts.CurReplyFrameSize,
5564 ioc->facts.ReplyQueueDepth);
5566 len += sprintf(buf+len, " MaxDevices = %d\n",
5567 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5568 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5571 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5572 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5574 ioc->facts.NumberOfPorts);
5575 if (ioc->bus_type == FC) {
5576 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5577 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5578 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5579 a[5], a[4], a[3], a[2], a[1], a[0]);
5581 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5582 ioc->fc_port_page0[p].WWNN.High,
5583 ioc->fc_port_page0[p].WWNN.Low,
5584 ioc->fc_port_page0[p].WWPN.High,
5585 ioc->fc_port_page0[p].WWPN.Low);
5589 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5592 #endif /* CONFIG_PROC_FS } */
5594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5596 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5599 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5600 sprintf(buf, " (Exp %02d%02d)",
5601 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5602 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5605 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5606 strcat(buf, " [MDBG]");
5610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5612 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5613 * @ioc: Pointer to MPT_ADAPTER structure
5614 * @buffer: Pointer to buffer where IOC summary info should be written
5615 * @size: Pointer to number of bytes we wrote (set by this routine)
5616 * @len: Offset at which to start writing in buffer
5617 * @showlan: Display LAN stuff?
5619 * This routine writes (english readable) ASCII text, which represents
5620 * a summary of IOC information, to a buffer.
5623 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5628 mpt_get_fw_exp_ver(expVer, ioc);
5631 * Shorter summary of attached ioc's...
5633 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5636 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5637 ioc->facts.FWVersion.Word,
5639 ioc->facts.NumberOfPorts,
5642 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5643 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5644 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5645 a[5], a[4], a[3], a[2], a[1], a[0]);
5649 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5651 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5655 y += sprintf(buffer+len+y, " (disabled)");
5657 y += sprintf(buffer+len+y, "\n");
5662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5666 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5668 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5669 * Management call based on input arg values. If TaskMgmt fails,
5670 * return associated SCSI request.
5671 * @ioc: Pointer to MPT_ADAPTER structure
5672 * @sleepFlag: Indicates if sleep or schedule must be called.
5674 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5675 * or a non-interrupt thread. In the former, must not call schedule().
5677 * Remark: A return of -1 is a FATAL error case, as it means a
5678 * FW reload/initialization failed.
5680 * Returns 0 for SUCCESS or -1 if FAILED.
5683 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5686 unsigned long flags;
5688 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5690 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5691 printk("MF count 0x%x !\n", ioc->mfcnt);
5694 /* Reset the adapter. Prevent more than 1 call to
5695 * mpt_do_ioc_recovery at any instant in time.
5697 spin_lock_irqsave(&ioc->diagLock, flags);
5698 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5699 spin_unlock_irqrestore(&ioc->diagLock, flags);
5702 ioc->diagPending = 1;
5704 spin_unlock_irqrestore(&ioc->diagLock, flags);
5706 /* FIXME: If do_ioc_recovery fails, repeat....
5709 /* The SCSI driver needs to adjust timeouts on all current
5710 * commands prior to the diagnostic reset being issued.
5711 * Prevents timeouts occuring during a diagnostic reset...very bad.
5712 * For all other protocol drivers, this is a no-op.
5718 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5719 if (MptResetHandlers[ii]) {
5720 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5722 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5724 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5725 ioc->name, ioc->alt_ioc->name, ii));
5726 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5732 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5733 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5738 ioc->alt_ioc->reload_fw = 0;
5740 spin_lock_irqsave(&ioc->diagLock, flags);
5741 ioc->diagPending = 0;
5743 ioc->alt_ioc->diagPending = 0;
5744 spin_unlock_irqrestore(&ioc->diagLock, flags);
5746 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5753 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5758 case MPI_EVENT_NONE:
5761 case MPI_EVENT_LOG_DATA:
5764 case MPI_EVENT_STATE_CHANGE:
5765 ds = "State Change";
5767 case MPI_EVENT_UNIT_ATTENTION:
5768 ds = "Unit Attention";
5770 case MPI_EVENT_IOC_BUS_RESET:
5771 ds = "IOC Bus Reset";
5773 case MPI_EVENT_EXT_BUS_RESET:
5774 ds = "External Bus Reset";
5776 case MPI_EVENT_RESCAN:
5777 ds = "Bus Rescan Event";
5778 /* Ok, do we need to do anything here? As far as
5779 I can tell, this is when a new device gets added
5782 case MPI_EVENT_LINK_STATUS_CHANGE:
5783 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5784 ds = "Link Status(FAILURE) Change";
5786 ds = "Link Status(ACTIVE) Change";
5788 case MPI_EVENT_LOOP_STATE_CHANGE:
5789 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5790 ds = "Loop State(LIP) Change";
5791 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5792 ds = "Loop State(LPE) Change"; /* ??? */
5794 ds = "Loop State(LPB) Change"; /* ??? */
5796 case MPI_EVENT_LOGOUT:
5799 case MPI_EVENT_EVENT_CHANGE:
5801 ds = "Events(ON) Change";
5803 ds = "Events(OFF) Change";
5805 case MPI_EVENT_INTEGRATED_RAID:
5807 u8 ReasonCode = (u8)(evData0 >> 16);
5808 switch (ReasonCode) {
5809 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5810 ds = "Integrated Raid: Volume Created";
5812 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5813 ds = "Integrated Raid: Volume Deleted";
5815 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5816 ds = "Integrated Raid: Volume Settings Changed";
5818 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5819 ds = "Integrated Raid: Volume Status Changed";
5821 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5822 ds = "Integrated Raid: Volume Physdisk Changed";
5824 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5825 ds = "Integrated Raid: Physdisk Created";
5827 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5828 ds = "Integrated Raid: Physdisk Deleted";
5830 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5831 ds = "Integrated Raid: Physdisk Settings Changed";
5833 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5834 ds = "Integrated Raid: Physdisk Status Changed";
5836 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5837 ds = "Integrated Raid: Domain Validation Needed";
5839 case MPI_EVENT_RAID_RC_SMART_DATA :
5840 ds = "Integrated Raid; Smart Data";
5842 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5843 ds = "Integrated Raid: Replace Action Started";
5846 ds = "Integrated Raid";
5851 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5852 ds = "SCSI Device Status Change";
5854 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5856 u8 ReasonCode = (u8)(evData0 >> 16);
5857 switch (ReasonCode) {
5858 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5859 ds = "SAS Device Status Change: Added";
5861 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5862 ds = "SAS Device Status Change: Deleted";
5864 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5865 ds = "SAS Device Status Change: SMART Data";
5867 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5868 ds = "SAS Device Status Change: No Persistancy Added";
5871 ds = "SAS Device Status Change: Unknown";
5876 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5877 ds = "Bus Timer Expired";
5879 case MPI_EVENT_QUEUE_FULL:
5882 case MPI_EVENT_SAS_SES:
5883 ds = "SAS SES Event";
5885 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5886 ds = "Persistent Table Full";
5888 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5889 ds = "SAS PHY Link Status";
5891 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5892 ds = "SAS Discovery Error";
5896 * MPT base "custom" events may be added here...
5905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5907 * ProcessEventNotification - Route a received EventNotificationReply to
5908 * all currently regeistered event handlers.
5909 * @ioc: Pointer to MPT_ADAPTER structure
5910 * @pEventReply: Pointer to EventNotification reply frame
5911 * @evHandlers: Pointer to integer, number of event handlers
5913 * Returns sum of event handlers return values.
5916 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5928 * Do platform normalization of values
5930 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5931 // evCtx = le32_to_cpu(pEventReply->EventContext);
5932 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5934 evData0 = le32_to_cpu(pEventReply->Data[0]);
5937 EventDescriptionStr(event, evData0, evStr);
5938 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5943 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5944 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5945 for (ii = 0; ii < evDataLen; ii++)
5946 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5951 * Do general / base driver event processing
5954 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5956 u8 evState = evData0 & 0xFF;
5958 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5960 /* Update EventState field in cached IocFacts */
5961 if (ioc->facts.Function) {
5962 ioc->facts.EventState = evState;
5971 * Should this event be logged? Events are written sequentially.
5972 * When buffer is full, start again at the top.
5974 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5977 idx = ioc->eventContext % ioc->eventLogSize;
5979 ioc->events[idx].event = event;
5980 ioc->events[idx].eventContext = ioc->eventContext;
5982 for (ii = 0; ii < 2; ii++) {
5984 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5986 ioc->events[idx].data[ii] = 0;
5989 ioc->eventContext++;
5994 * Call each currently registered protocol event handler.
5996 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5997 if (MptEvHandlers[ii]) {
5998 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6000 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6004 /* FIXME? Examine results here? */
6007 * If needed, send (a single) EventAck.
6009 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6010 devtprintk((MYIOC_s_WARN_FMT
6011 "EventAck required\n",ioc->name));
6012 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6013 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6018 *evHandlers = handlers;
6022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6024 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6025 * @ioc: Pointer to MPT_ADAPTER structure
6026 * @log_info: U32 LogInfo reply word from the IOC
6028 * Refer to lsi/fc_log.h.
6031 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6033 static char *subcl_str[8] = {
6034 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6035 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6037 u8 subcl = (log_info >> 24) & 0x7;
6039 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6040 ioc->name, log_info, subcl_str[subcl]);
6043 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6045 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
6046 * @ioc: Pointer to MPT_ADAPTER structure
6047 * @mr: Pointer to MPT reply frame
6048 * @log_info: U32 LogInfo word from the IOC
6050 * Refer to lsi/sp_log.h.
6053 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
6055 u32 info = log_info & 0x00FF0000;
6056 char *desc = "unknown";
6060 desc = "bug! MID not found";
6061 if (ioc->reload_fw == 0)
6066 desc = "Parity Error";
6070 desc = "ASYNC Outbound Overrun";
6074 desc = "SYNC Offset Error";
6082 desc = "Msg In Overflow";
6090 desc = "Outbound DMA Overrun";
6094 desc = "Task Management";
6098 desc = "Device Problem";
6102 desc = "Invalid Phase Change";
6106 desc = "Untagged Table Size";
6111 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6114 /* strings for sas loginfo */
6115 static char *originator_str[] = {
6120 static char *iop_code_str[] = {
6122 "Invalid SAS Address", /* 01h */
6124 "Invalid Page", /* 03h */
6126 "Task Terminated" /* 05h */
6128 static char *pl_code_str[] = {
6130 "Open Failure", /* 01h */
6131 "Invalid Scatter Gather List", /* 02h */
6132 "Wrong Relative Offset or Frame Length", /* 03h */
6133 "Frame Transfer Error", /* 04h */
6134 "Transmit Frame Connected Low", /* 05h */
6135 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6136 "SATA Read Log Receive Data Error", /* 07h */
6137 "SATA NCQ Fail All Commands After Error", /* 08h */
6138 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6139 "Receive Frame Invalid Message", /* 0Ah */
6140 "Receive Context Message Valid Error", /* 0Bh */
6141 "Receive Frame Current Frame Error", /* 0Ch */
6142 "SATA Link Down", /* 0Dh */
6143 "Discovery SATA Init W IOS", /* 0Eh */
6144 "Config Invalid Page", /* 0Fh */
6145 "Discovery SATA Init Timeout", /* 10h */
6148 "IO Not Yet Executed", /* 13h */
6149 "IO Executed", /* 14h */
6161 "Enclosure Management" /* 20h */
6164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6166 * mpt_sas_log_info - Log information returned from SAS IOC.
6167 * @ioc: Pointer to MPT_ADAPTER structure
6168 * @log_info: U32 LogInfo reply word from the IOC
6170 * Refer to lsi/mpi_log_sas.h.
6173 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6175 union loginfo_type {
6184 union loginfo_type sas_loginfo;
6185 char *code_desc = NULL;
6187 sas_loginfo.loginfo = log_info;
6188 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6189 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6191 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6192 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6193 code_desc = iop_code_str[sas_loginfo.dw.code];
6194 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6195 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6196 code_desc = pl_code_str[sas_loginfo.dw.code];
6199 if (code_desc != NULL)
6200 printk(MYIOC_s_INFO_FMT
6201 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6202 " SubCode(0x%04x)\n",
6205 originator_str[sas_loginfo.dw.originator],
6207 sas_loginfo.dw.subcode);
6209 printk(MYIOC_s_INFO_FMT
6210 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6211 " SubCode(0x%04x)\n",
6214 originator_str[sas_loginfo.dw.originator],
6215 sas_loginfo.dw.code,
6216 sas_loginfo.dw.subcode);
6219 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6221 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6222 * @ioc: Pointer to MPT_ADAPTER structure
6223 * @ioc_status: U32 IOCStatus word from IOC
6224 * @mf: Pointer to MPT request frame
6226 * Refer to lsi/mpi.h.
6229 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6231 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6235 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6236 desc = "Invalid Function";
6239 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6243 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6244 desc = "Invalid SGL";
6247 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6248 desc = "Internal Error";
6251 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6255 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6256 desc = "Insufficient Resources";
6259 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6260 desc = "Invalid Field";
6263 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6264 desc = "Invalid State";
6267 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6268 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6269 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6270 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6271 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6272 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6273 /* No message for Config IOCStatus values */
6276 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6277 /* No message for recovered error
6278 desc = "SCSI Recovered Error";
6282 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6283 desc = "SCSI Invalid Bus";
6286 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6287 desc = "SCSI Invalid TargetID";
6290 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6292 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6293 U8 cdb = pScsiReq->CDB[0];
6294 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6295 desc = "SCSI Device Not There";
6300 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6301 desc = "SCSI Data Overrun";
6304 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6305 /* This error is checked in scsi_io_done(). Skip.
6306 desc = "SCSI Data Underrun";
6310 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6311 desc = "SCSI I/O Data Error";
6314 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6315 desc = "SCSI Protocol Error";
6318 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6319 desc = "SCSI Task Terminated";
6322 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6323 desc = "SCSI Residual Mismatch";
6326 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6327 desc = "SCSI Task Management Failed";
6330 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6331 desc = "SCSI IOC Terminated";
6334 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6335 desc = "SCSI Ext Terminated";
6343 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6346 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6347 EXPORT_SYMBOL(mpt_attach);
6348 EXPORT_SYMBOL(mpt_detach);
6350 EXPORT_SYMBOL(mpt_resume);
6351 EXPORT_SYMBOL(mpt_suspend);
6353 EXPORT_SYMBOL(ioc_list);
6354 EXPORT_SYMBOL(mpt_proc_root_dir);
6355 EXPORT_SYMBOL(mpt_register);
6356 EXPORT_SYMBOL(mpt_deregister);
6357 EXPORT_SYMBOL(mpt_event_register);
6358 EXPORT_SYMBOL(mpt_event_deregister);
6359 EXPORT_SYMBOL(mpt_reset_register);
6360 EXPORT_SYMBOL(mpt_reset_deregister);
6361 EXPORT_SYMBOL(mpt_device_driver_register);
6362 EXPORT_SYMBOL(mpt_device_driver_deregister);
6363 EXPORT_SYMBOL(mpt_get_msg_frame);
6364 EXPORT_SYMBOL(mpt_put_msg_frame);
6365 EXPORT_SYMBOL(mpt_free_msg_frame);
6366 EXPORT_SYMBOL(mpt_add_sge);
6367 EXPORT_SYMBOL(mpt_send_handshake_request);
6368 EXPORT_SYMBOL(mpt_verify_adapter);
6369 EXPORT_SYMBOL(mpt_GetIocState);
6370 EXPORT_SYMBOL(mpt_print_ioc_summary);
6371 EXPORT_SYMBOL(mpt_lan_index);
6372 EXPORT_SYMBOL(mpt_stm_index);
6373 EXPORT_SYMBOL(mpt_HardResetHandler);
6374 EXPORT_SYMBOL(mpt_config);
6375 EXPORT_SYMBOL(mpt_toolbox);
6376 EXPORT_SYMBOL(mpt_findImVolumes);
6377 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6378 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6379 EXPORT_SYMBOL(mpt_free_fw_memory);
6380 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6381 EXPORT_SYMBOL(mpt_alt_ioc_wait);
6382 EXPORT_SYMBOL(mptbase_GetFcPortPage0);
6385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6387 * fusion_init - Fusion MPT base driver initialization routine.
6389 * Returns 0 for success, non-zero for failure.
6396 show_mptmod_ver(my_NAME, my_VERSION);
6397 printk(KERN_INFO COPYRIGHT "\n");
6399 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6400 MptCallbacks[i] = NULL;
6401 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6402 MptEvHandlers[i] = NULL;
6403 MptResetHandlers[i] = NULL;
6406 /* Register ourselves (mptbase) in order to facilitate
6407 * EventNotification handling.
6409 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6411 /* Register for hard reset handling callbacks.
6413 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6414 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6419 #ifdef CONFIG_PROC_FS
6420 (void) procmpt_create();
6425 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6427 * fusion_exit - Perform driver unload cleanup.
6429 * This routine frees all resources associated with each MPT adapter
6430 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6436 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6438 mpt_reset_deregister(mpt_base_index);
6440 #ifdef CONFIG_PROC_FS
6445 module_init(fusion_init);
6446 module_exit(fusion_exit);