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-2007 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsi.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/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
68 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
69 #define my_NAME "Fusion MPT base driver"
70 #define my_VERSION MPT_LINUX_VERSION_COMMON
71 #define MYNAM "mptbase"
73 MODULE_AUTHOR(MODULEAUTHOR);
74 MODULE_DESCRIPTION(my_NAME);
75 MODULE_LICENSE("GPL");
76 MODULE_VERSION(my_VERSION);
81 static int mpt_msi_enable;
82 module_param(mpt_msi_enable, int, 0);
83 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
85 static int mpt_channel_mapping;
86 module_param(mpt_channel_mapping, int, 0);
87 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
90 static int mfcounter = 0;
91 #define PRINT_MF_COUNT 20000
94 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
98 int mpt_lan_index = -1;
99 int mpt_stm_index = -1;
101 struct proc_dir_entry *mpt_proc_root_dir;
103 #define WHOINIT_UNKNOWN 0xAA
105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
109 /* Adapter link list */
111 /* Callback lookup table */
112 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
113 /* Protocol driver class lookup table */
114 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
115 /* Event handler lookup table */
116 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
117 /* Reset handler lookup table */
118 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
119 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
121 static int mpt_base_index = -1;
122 static int last_drv_idx = -1;
124 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
126 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
130 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
131 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
132 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
133 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
135 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
136 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
137 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
138 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
140 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
141 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
142 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
143 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
144 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
145 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
146 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
147 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
148 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
149 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
150 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
151 static int PrimeIocFifos(MPT_ADAPTER *ioc);
152 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
153 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
154 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
155 static int GetLanConfigPages(MPT_ADAPTER *ioc);
156 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
157 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
158 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
159 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
160 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
161 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
162 static void mpt_timer_expired(unsigned long data);
163 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
164 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
165 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
166 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
168 #ifdef CONFIG_PROC_FS
169 static int procmpt_summary_read(char *buf, char **start, off_t offset,
170 int request, int *eof, void *data);
171 static int procmpt_version_read(char *buf, char **start, off_t offset,
172 int request, int *eof, void *data);
173 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
174 int request, int *eof, void *data);
176 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
178 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
179 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
180 #ifdef MPT_DEBUG_REPLY
181 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
183 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
184 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
185 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
186 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
187 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
189 /* module entry point */
190 static int __init fusion_init (void);
191 static void __exit fusion_exit (void);
193 #define CHIPREG_READ32(addr) readl_relaxed(addr)
194 #define CHIPREG_READ32_dmasync(addr) readl(addr)
195 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
196 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
197 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
200 pci_disable_io_access(struct pci_dev *pdev)
204 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
206 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
210 pci_enable_io_access(struct pci_dev *pdev)
214 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
216 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
220 * Process turbo (context) reply...
223 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
225 MPT_FRAME_HDR *mf = NULL;
226 MPT_FRAME_HDR *mr = NULL;
230 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
233 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
234 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
235 req_idx = pa & 0x0000FFFF;
236 cb_idx = (pa & 0x00FF0000) >> 16;
237 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
239 case MPI_CONTEXT_REPLY_TYPE_LAN:
240 cb_idx = mpt_lan_index;
242 * Blind set of mf to NULL here was fatal
243 * after lan_reply says "freeme"
244 * Fix sort of combined with an optimization here;
245 * added explicit check for case where lan_reply
246 * was just returning 1 and doing nothing else.
247 * For this case skip the callback, but set up
248 * proper mf value first here:-)
250 if ((pa & 0x58000000) == 0x58000000) {
251 req_idx = pa & 0x0000FFFF;
252 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
253 mpt_free_msg_frame(ioc, mf);
258 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
260 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
261 cb_idx = mpt_stm_index;
262 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
269 /* Check for (valid) IO callback! */
270 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
271 MptCallbacks[cb_idx] == NULL) {
272 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
273 __FUNCTION__, ioc->name, cb_idx);
277 if (MptCallbacks[cb_idx](ioc, mf, mr))
278 mpt_free_msg_frame(ioc, mf);
284 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
295 /* non-TURBO reply! Hmmm, something may be up...
296 * Newest turbo reply mechanism; get address
297 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
300 /* Map DMA address of reply header to cpu address.
301 * pa is 32 bits - but the dma address may be 32 or 64 bits
302 * get offset based only only the low addresses
305 reply_dma_low = (pa <<= 1);
306 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
307 (reply_dma_low - ioc->reply_frames_low_dma));
309 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
310 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
311 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
313 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
314 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
315 DBG_DUMP_REPLY_FRAME(mr)
317 /* Check/log IOC log info
319 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
320 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
321 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
322 if (ioc->bus_type == FC)
323 mpt_fc_log_info(ioc, log_info);
324 else if (ioc->bus_type == SPI)
325 mpt_spi_log_info(ioc, log_info);
326 else if (ioc->bus_type == SAS)
327 mpt_sas_log_info(ioc, log_info);
330 #ifdef MPT_DEBUG_REPLY
331 if (ioc_stat & MPI_IOCSTATUS_MASK)
332 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
335 /* Check for (valid) IO callback! */
336 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
337 MptCallbacks[cb_idx] == NULL) {
338 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
339 __FUNCTION__, ioc->name, cb_idx);
344 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
347 /* Flush (non-TURBO) reply with a WRITE! */
348 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
351 mpt_free_msg_frame(ioc, mf);
355 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
357 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
358 * @irq: irq number (not used)
359 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
361 * This routine is registered via the request_irq() kernel API call,
362 * and handles all interrupts generated from a specific MPT adapter
363 * (also referred to as a IO Controller or IOC).
364 * This routine must clear the interrupt from the adapter and does
365 * so by reading the reply FIFO. Multiple replies may be processed
366 * per single call to this routine.
368 * This routine handles register-level access of the adapter but
369 * dispatches (calls) a protocol-specific callback routine to handle
370 * the protocol-specific details of the MPT request completion.
373 mpt_interrupt(int irq, void *bus_id)
375 MPT_ADAPTER *ioc = bus_id;
376 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
378 if (pa == 0xFFFFFFFF)
382 * Drain the reply FIFO!
385 if (pa & MPI_ADDRESS_REPLY_A_BIT)
388 mpt_turbo_reply(ioc, pa);
389 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
390 } while (pa != 0xFFFFFFFF);
395 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
397 * mpt_base_reply - MPT base driver's callback routine
398 * @ioc: Pointer to MPT_ADAPTER structure
399 * @mf: Pointer to original MPT request frame
400 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
402 * MPT base driver's callback routine; all base driver
403 * "internal" request/reply processing is routed here.
404 * Currently used for EventNotification and EventAck handling.
406 * Returns 1 indicating original alloc'd request frame ptr
407 * should be freed, or 0 if it shouldn't.
410 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
415 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
417 #if defined(MPT_DEBUG_MSG_FRAME)
418 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
419 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
420 DBG_DUMP_REQUEST_FRAME_HDR(mf)
424 func = reply->u.hdr.Function;
425 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
428 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
429 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
433 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
434 if (results != evHandlers) {
435 /* CHECKME! Any special handling needed here? */
436 devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
437 ioc->name, evHandlers, results));
441 * Hmmm... It seems that EventNotificationReply is an exception
442 * to the rule of one reply per request.
444 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
447 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
448 ioc->name, pEvReply));
451 #ifdef CONFIG_PROC_FS
452 // LogEvent(ioc, pEvReply);
455 } else if (func == MPI_FUNCTION_EVENT_ACK) {
456 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
458 } else if (func == MPI_FUNCTION_CONFIG) {
462 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
463 ioc->name, mf, reply));
465 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
468 /* disable timer and remove from linked list */
469 del_timer(&pCfg->timer);
471 spin_lock_irqsave(&ioc->FreeQlock, flags);
472 list_del(&pCfg->linkage);
473 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
476 * If IOC Status is SUCCESS, save the header
477 * and set the status code to GOOD.
479 pCfg->status = MPT_CONFIG_ERROR;
481 ConfigReply_t *pReply = (ConfigReply_t *)reply;
484 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
485 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
486 status, le32_to_cpu(pReply->IOCLogInfo)));
488 pCfg->status = status;
489 if (status == MPI_IOCSTATUS_SUCCESS) {
490 if ((pReply->Header.PageType &
491 MPI_CONFIG_PAGETYPE_MASK) ==
492 MPI_CONFIG_PAGETYPE_EXTENDED) {
493 pCfg->cfghdr.ehdr->ExtPageLength =
494 le16_to_cpu(pReply->ExtPageLength);
495 pCfg->cfghdr.ehdr->ExtPageType =
498 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
500 /* If this is a regular header, save PageLength. */
501 /* LMP Do this better so not using a reserved field! */
502 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
503 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
504 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
509 * Wake up the original calling thread
514 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
515 /* we should be always getting a reply frame */
516 memcpy(ioc->persist_reply_frame, reply,
517 min(MPT_DEFAULT_FRAME_SIZE,
518 4*reply->u.reply.MsgLength));
519 del_timer(&ioc->persist_timer);
520 ioc->persist_wait_done = 1;
523 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
528 * Conditionally tell caller to free the original
529 * EventNotification/EventAck/unexpected request frame!
534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
536 * mpt_register - Register protocol-specific main callback handler.
537 * @cbfunc: callback function pointer
538 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
540 * This routine is called by a protocol-specific driver (SCSI host,
541 * LAN, SCSI target) to register its reply callback routine. Each
542 * protocol-specific driver must do this before it will be able to
543 * use any IOC resources, such as obtaining request frames.
545 * NOTES: The SCSI protocol driver currently calls this routine thrice
546 * in order to register separate callbacks; one for "normal" SCSI IO;
547 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
549 * Returns a positive integer valued "handle" in the
550 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
551 * Any non-positive return value (including zero!) should be considered
552 * an error by the caller.
555 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
562 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
563 * (slot/handle 0 is reserved!)
565 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
566 if (MptCallbacks[i] == NULL) {
567 MptCallbacks[i] = cbfunc;
568 MptDriverClass[i] = dclass;
569 MptEvHandlers[i] = NULL;
578 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
580 * mpt_deregister - Deregister a protocol drivers resources.
581 * @cb_idx: previously registered callback handle
583 * Each protocol-specific driver should call this routine when its
584 * module is unloaded.
587 mpt_deregister(int cb_idx)
589 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
590 MptCallbacks[cb_idx] = NULL;
591 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
592 MptEvHandlers[cb_idx] = NULL;
598 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
600 * mpt_event_register - Register protocol-specific event callback
602 * @cb_idx: previously registered (via mpt_register) callback handle
603 * @ev_cbfunc: callback function
605 * This routine can be called by one or more protocol-specific drivers
606 * if/when they choose to be notified of MPT events.
608 * Returns 0 for success.
611 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
613 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
616 MptEvHandlers[cb_idx] = ev_cbfunc;
620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
622 * mpt_event_deregister - Deregister protocol-specific event callback
624 * @cb_idx: previously registered callback handle
626 * Each protocol-specific driver should call this routine
627 * when it does not (or can no longer) handle events,
628 * or when its module is unloaded.
631 mpt_event_deregister(int cb_idx)
633 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
636 MptEvHandlers[cb_idx] = NULL;
639 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
641 * mpt_reset_register - Register protocol-specific IOC reset handler.
642 * @cb_idx: previously registered (via mpt_register) callback handle
643 * @reset_func: reset function
645 * This routine can be called by one or more protocol-specific drivers
646 * if/when they choose to be notified of IOC resets.
648 * Returns 0 for success.
651 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
653 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
656 MptResetHandlers[cb_idx] = reset_func;
660 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
662 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
663 * @cb_idx: previously registered callback handle
665 * Each protocol-specific driver should call this routine
666 * when it does not (or can no longer) handle IOC reset handling,
667 * or when its module is unloaded.
670 mpt_reset_deregister(int cb_idx)
672 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
675 MptResetHandlers[cb_idx] = NULL;
678 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
680 * mpt_device_driver_register - Register device driver hooks
681 * @dd_cbfunc: driver callbacks struct
682 * @cb_idx: MPT protocol driver index
685 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
688 const struct pci_device_id *id;
690 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
693 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
695 /* call per pci device probe entry point */
696 list_for_each_entry(ioc, &ioc_list, list) {
697 id = ioc->pcidev->driver ?
698 ioc->pcidev->driver->id_table : NULL;
699 if (dd_cbfunc->probe)
700 dd_cbfunc->probe(ioc->pcidev, id);
706 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
708 * mpt_device_driver_deregister - DeRegister device driver hooks
709 * @cb_idx: MPT protocol driver index
712 mpt_device_driver_deregister(int cb_idx)
714 struct mpt_pci_driver *dd_cbfunc;
717 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
720 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
722 list_for_each_entry(ioc, &ioc_list, list) {
723 if (dd_cbfunc->remove)
724 dd_cbfunc->remove(ioc->pcidev);
727 MptDeviceDriverHandlers[cb_idx] = NULL;
731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
733 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
734 * allocated per MPT adapter.
735 * @handle: Handle of registered MPT protocol driver
736 * @ioc: Pointer to MPT adapter structure
738 * Returns pointer to a MPT request frame or %NULL if none are available
739 * or IOC is not active.
742 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
746 u16 req_idx; /* Request index */
748 /* validate handle and ioc identifier */
752 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
755 /* If interrupts are not attached, do not return a request frame */
759 spin_lock_irqsave(&ioc->FreeQlock, flags);
760 if (!list_empty(&ioc->FreeQ)) {
763 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
764 u.frame.linkage.list);
765 list_del(&mf->u.frame.linkage.list);
766 mf->u.frame.linkage.arg1 = 0;
767 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
768 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
770 req_idx = req_offset / ioc->req_sz;
771 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
772 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
773 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
780 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
784 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
786 if (mfcounter == PRINT_MF_COUNT)
787 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
790 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
791 ioc->name, handle, ioc->id, mf));
795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
797 * mpt_put_msg_frame - Send a protocol specific MPT request frame
799 * @handle: Handle of registered MPT protocol driver
800 * @ioc: Pointer to MPT adapter structure
801 * @mf: Pointer to MPT request frame
803 * This routine posts a MPT request frame to the request post FIFO of a
804 * specific MPT adapter.
807 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
811 u16 req_idx; /* Request index */
813 /* ensure values are reset properly! */
814 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
815 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
817 req_idx = req_offset / ioc->req_sz;
818 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
819 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
821 #ifdef MPT_DEBUG_MSG_FRAME
823 u32 *m = mf->u.frame.hwhdr.__hdr;
826 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
828 n = ioc->req_sz/4 - 1;
831 for (ii=0; ii<=n; ii++) {
832 if (ii && ((ii%8)==0))
833 printk("\n" KERN_INFO " ");
834 printk(" %08x", le32_to_cpu(m[ii]));
840 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
841 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]));
842 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
845 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
847 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
848 * @handle: Handle of registered MPT protocol driver
849 * @ioc: Pointer to MPT adapter structure
850 * @mf: Pointer to MPT request frame
852 * This routine places a MPT request frame back on the MPT adapter's
856 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
860 /* Put Request back on FreeQ! */
861 spin_lock_irqsave(&ioc->FreeQlock, flags);
862 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
863 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
867 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
870 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
872 * mpt_add_sge - Place a simple SGE at address pAddr.
873 * @pAddr: virtual address for SGE
874 * @flagslength: SGE flags and data transfer length
875 * @dma_addr: Physical address
877 * This routine places a MPT request frame back on the MPT adapter's
881 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
883 if (sizeof(dma_addr_t) == sizeof(u64)) {
884 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
885 u32 tmp = dma_addr & 0xFFFFFFFF;
887 pSge->FlagsLength = cpu_to_le32(flagslength);
888 pSge->Address.Low = cpu_to_le32(tmp);
889 tmp = (u32) ((u64)dma_addr >> 32);
890 pSge->Address.High = cpu_to_le32(tmp);
893 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
894 pSge->FlagsLength = cpu_to_le32(flagslength);
895 pSge->Address = cpu_to_le32(dma_addr);
899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
901 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
902 * @handle: Handle of registered MPT protocol driver
903 * @ioc: Pointer to MPT adapter structure
904 * @reqBytes: Size of the request in bytes
905 * @req: Pointer to MPT request frame
906 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
908 * This routine is used exclusively to send MptScsiTaskMgmt
909 * requests since they are required to be sent via doorbell handshake.
911 * NOTE: It is the callers responsibility to byte-swap fields in the
912 * request which are greater than 1 byte in size.
914 * Returns 0 for success, non-zero for failure.
917 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
923 /* State is known to be good upon entering
924 * this function so issue the bus reset
929 * Emulate what mpt_put_msg_frame() does /wrt to sanity
930 * setting cb_idx/req_idx. But ONLY if this request
931 * is in proper (pre-alloc'd) request buffer range...
933 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
934 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
935 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
936 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
937 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
940 /* Make sure there are no doorbells */
941 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
943 CHIPREG_WRITE32(&ioc->chip->Doorbell,
944 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
945 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
947 /* Wait for IOC doorbell int */
948 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
952 /* Read doorbell and check for active bit */
953 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
956 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
959 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
961 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
965 /* Send request via doorbell handshake */
966 req_as_bytes = (u8 *) req;
967 for (ii = 0; ii < reqBytes/4; ii++) {
970 word = ((req_as_bytes[(ii*4) + 0] << 0) |
971 (req_as_bytes[(ii*4) + 1] << 8) |
972 (req_as_bytes[(ii*4) + 2] << 16) |
973 (req_as_bytes[(ii*4) + 3] << 24));
974 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
975 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
981 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
986 /* Make sure there are no doorbells */
987 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
994 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
995 * @ioc: Pointer to MPT adapter structure
996 * @access_control_value: define bits below
997 * @sleepFlag: Specifies whether the process can sleep
999 * Provides mechanism for the host driver to control the IOC's
1000 * Host Page Buffer access.
1002 * Access Control Value - bits[15:12]
1004 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1005 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1006 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1008 * Returns 0 for success, non-zero for failure.
1012 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1016 /* return if in use */
1017 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1018 & MPI_DOORBELL_ACTIVE)
1021 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1023 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1024 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1025 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1026 (access_control_value<<12)));
1028 /* Wait for IOC to clear Doorbell Status bit */
1029 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1037 * mpt_host_page_alloc - allocate system memory for the fw
1038 * @ioc: Pointer to pointer to IOC adapter
1039 * @ioc_init: Pointer to ioc init config page
1041 * If we already allocated memory in past, then resend the same pointer.
1042 * Returns 0 for success, non-zero for failure.
1045 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1049 u32 host_page_buffer_sz=0;
1051 if(!ioc->HostPageBuffer) {
1053 host_page_buffer_sz =
1054 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1056 if(!host_page_buffer_sz)
1057 return 0; /* fw doesn't need any host buffers */
1059 /* spin till we get enough memory */
1060 while(host_page_buffer_sz > 0) {
1062 if((ioc->HostPageBuffer = pci_alloc_consistent(
1064 host_page_buffer_sz,
1065 &ioc->HostPageBuffer_dma)) != NULL) {
1067 dinitprintk((MYIOC_s_INFO_FMT
1068 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1069 ioc->name, ioc->HostPageBuffer,
1070 (u32)ioc->HostPageBuffer_dma,
1071 host_page_buffer_sz));
1072 ioc->alloc_total += host_page_buffer_sz;
1073 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1077 host_page_buffer_sz -= (4*1024);
1081 if(!ioc->HostPageBuffer) {
1082 printk(MYIOC_s_ERR_FMT
1083 "Failed to alloc memory for host_page_buffer!\n",
1088 psge = (char *)&ioc_init->HostPageBufferSGE;
1089 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1090 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1091 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1092 MPI_SGE_FLAGS_HOST_TO_IOC |
1093 MPI_SGE_FLAGS_END_OF_BUFFER;
1094 if (sizeof(dma_addr_t) == sizeof(u64)) {
1095 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1097 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1098 flags_length |= ioc->HostPageBuffer_sz;
1099 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1100 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1107 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1108 * @iocid: IOC unique identifier (integer)
1109 * @iocpp: Pointer to pointer to IOC adapter
1111 * Given a unique IOC identifier, set pointer to the associated MPT
1112 * adapter structure.
1114 * Returns iocid and sets iocpp if iocid is found.
1115 * Returns -1 if iocid is not found.
1118 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1122 list_for_each_entry(ioc,&ioc_list,list) {
1123 if (ioc->id == iocid) {
1133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1135 * mpt_attach - Install a PCI intelligent MPT adapter.
1136 * @pdev: Pointer to pci_dev structure
1137 * @id: PCI device ID information
1139 * This routine performs all the steps necessary to bring the IOC of
1140 * a MPT adapter to a OPERATIONAL state. This includes registering
1141 * memory regions, registering the interrupt, and allocating request
1142 * and reply memory pools.
1144 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1147 * Returns 0 for success, non-zero for failure.
1149 * TODO: Add support for polled controllers
1152 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1156 unsigned long mem_phys;
1164 static int mpt_ids = 0;
1165 #ifdef CONFIG_PROC_FS
1166 struct proc_dir_entry *dent, *ent;
1169 if (pci_enable_device(pdev))
1172 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1174 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1175 dprintk((KERN_INFO MYNAM
1176 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1177 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1178 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1182 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1183 dprintk((KERN_INFO MYNAM
1184 ": Using 64 bit consistent mask\n"));
1186 dprintk((KERN_INFO MYNAM
1187 ": Not using 64 bit consistent mask\n"));
1189 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1191 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1194 ioc->alloc_total = sizeof(MPT_ADAPTER);
1195 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1196 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1199 ioc->diagPending = 0;
1200 spin_lock_init(&ioc->diagLock);
1201 spin_lock_init(&ioc->initializing_hba_lock);
1203 /* Initialize the event logging.
1205 ioc->eventTypes = 0; /* None */
1206 ioc->eventContext = 0;
1207 ioc->eventLogSize = 0;
1214 ioc->cached_fw = NULL;
1216 /* Initilize SCSI Config Data structure
1218 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1220 /* Initialize the running configQ head.
1222 INIT_LIST_HEAD(&ioc->configQ);
1224 /* Initialize the fc rport list head.
1226 INIT_LIST_HEAD(&ioc->fc_rports);
1228 /* Find lookup slot. */
1229 INIT_LIST_HEAD(&ioc->list);
1230 ioc->id = mpt_ids++;
1232 mem_phys = msize = 0;
1234 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1235 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1238 /* Get I/O space! */
1239 port = pci_resource_start(pdev, ii);
1240 psize = pci_resource_len(pdev,ii);
1245 mem_phys = pci_resource_start(pdev, ii);
1246 msize = pci_resource_len(pdev,ii);
1249 ioc->mem_size = msize;
1252 /* Get logical ptr for PciMem0 space */
1253 /*mem = ioremap(mem_phys, msize);*/
1254 mem = ioremap(mem_phys, msize);
1256 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1261 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1263 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1264 &ioc->facts, &ioc->pfacts[0]));
1266 ioc->mem_phys = mem_phys;
1267 ioc->chip = (SYSIF_REGS __iomem *)mem;
1269 /* Save Port IO values in case we need to do downloadboot */
1271 u8 *pmem = (u8*)port;
1272 ioc->pio_mem_phys = port;
1273 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1276 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1277 ioc->prod_name = "LSIFC909";
1280 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1281 ioc->prod_name = "LSIFC929";
1284 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1285 ioc->prod_name = "LSIFC919";
1288 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1289 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1291 if (revision < XL_929) {
1292 ioc->prod_name = "LSIFC929X";
1293 /* 929X Chip Fix. Set Split transactions level
1294 * for PCIX. Set MOST bits to zero.
1296 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1298 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1300 ioc->prod_name = "LSIFC929XL";
1301 /* 929XL Chip Fix. Set MMRBC to 0x08.
1303 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1305 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1308 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1309 ioc->prod_name = "LSIFC919X";
1311 /* 919X Chip Fix. Set Split transactions level
1312 * for PCIX. Set MOST bits to zero.
1314 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1316 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1318 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1319 ioc->prod_name = "LSIFC939X";
1321 ioc->errata_flag_1064 = 1;
1323 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1324 ioc->prod_name = "LSIFC949X";
1326 ioc->errata_flag_1064 = 1;
1328 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1329 ioc->prod_name = "LSIFC949E";
1332 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1333 ioc->prod_name = "LSI53C1030";
1334 ioc->bus_type = SPI;
1335 /* 1030 Chip Fix. Disable Split transactions
1336 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1338 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1339 if (revision < C0_1030) {
1340 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1342 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1345 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1346 ioc->prod_name = "LSI53C1035";
1347 ioc->bus_type = SPI;
1349 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1350 ioc->prod_name = "LSISAS1064";
1351 ioc->bus_type = SAS;
1352 ioc->errata_flag_1064 = 1;
1354 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1355 ioc->prod_name = "LSISAS1068";
1356 ioc->bus_type = SAS;
1357 ioc->errata_flag_1064 = 1;
1359 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1360 ioc->prod_name = "LSISAS1064E";
1361 ioc->bus_type = SAS;
1363 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1364 ioc->prod_name = "LSISAS1068E";
1365 ioc->bus_type = SAS;
1367 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
1368 ioc->prod_name = "LSISAS1078";
1369 ioc->bus_type = SAS;
1372 if (ioc->errata_flag_1064)
1373 pci_disable_io_access(pdev);
1375 sprintf(ioc->name, "ioc%d", ioc->id);
1377 spin_lock_init(&ioc->FreeQlock);
1380 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1382 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1384 /* Set lookup ptr. */
1385 list_add_tail(&ioc->list, &ioc_list);
1387 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1389 mpt_detect_bound_ports(ioc, pdev);
1391 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1393 printk(KERN_WARNING MYNAM
1394 ": WARNING - %s did not initialize properly! (%d)\n",
1397 list_del(&ioc->list);
1399 ioc->alt_ioc->alt_ioc = NULL;
1402 pci_set_drvdata(pdev, NULL);
1406 /* call per device driver probe entry point */
1407 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1408 if(MptDeviceDriverHandlers[ii] &&
1409 MptDeviceDriverHandlers[ii]->probe) {
1410 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1414 #ifdef CONFIG_PROC_FS
1416 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1418 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1420 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1422 ent->read_proc = procmpt_iocinfo_read;
1425 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1427 ent->read_proc = procmpt_summary_read;
1436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1438 * mpt_detach - Remove a PCI intelligent MPT adapter.
1439 * @pdev: Pointer to pci_dev structure
1443 mpt_detach(struct pci_dev *pdev)
1445 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1449 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1450 remove_proc_entry(pname, NULL);
1451 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1452 remove_proc_entry(pname, NULL);
1453 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1454 remove_proc_entry(pname, NULL);
1456 /* call per device driver remove entry point */
1457 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1458 if(MptDeviceDriverHandlers[ii] &&
1459 MptDeviceDriverHandlers[ii]->remove) {
1460 MptDeviceDriverHandlers[ii]->remove(pdev);
1464 /* Disable interrupts! */
1465 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1468 synchronize_irq(pdev->irq);
1470 /* Clear any lingering interrupt */
1471 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1473 CHIPREG_READ32(&ioc->chip->IntStatus);
1475 mpt_adapter_dispose(ioc);
1477 pci_set_drvdata(pdev, NULL);
1480 /**************************************************************************
1484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1486 * mpt_suspend - Fusion MPT base driver suspend routine.
1487 * @pdev: Pointer to pci_dev structure
1488 * @state: new state to enter
1491 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1494 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1496 device_state=pci_choose_state(pdev, state);
1498 printk(MYIOC_s_INFO_FMT
1499 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1500 ioc->name, pdev, pci_name(pdev), device_state);
1502 pci_save_state(pdev);
1504 /* put ioc into READY_STATE */
1505 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1506 printk(MYIOC_s_ERR_FMT
1507 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1510 /* disable interrupts */
1511 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1514 /* Clear any lingering interrupt */
1515 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1517 pci_disable_device(pdev);
1518 pci_set_power_state(pdev, device_state);
1523 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1525 * mpt_resume - Fusion MPT base driver resume routine.
1526 * @pdev: Pointer to pci_dev structure
1529 mpt_resume(struct pci_dev *pdev)
1531 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1532 u32 device_state = pdev->current_state;
1535 printk(MYIOC_s_INFO_FMT
1536 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1537 ioc->name, pdev, pci_name(pdev), device_state);
1539 pci_set_power_state(pdev, 0);
1540 pci_restore_state(pdev);
1541 pci_enable_device(pdev);
1543 /* enable interrupts */
1544 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1547 printk(MYIOC_s_INFO_FMT
1548 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1550 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1551 CHIPREG_READ32(&ioc->chip->Doorbell));
1553 /* bring ioc to operational state */
1554 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1555 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1556 printk(MYIOC_s_INFO_FMT
1557 "pci-resume: Cannot recover, error:[%x]\n",
1558 ioc->name, recovery_state);
1560 printk(MYIOC_s_INFO_FMT
1561 "pci-resume: success\n", ioc->name);
1569 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1571 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1572 ioc->bus_type != SPI) ||
1573 (MptDriverClass[index] == MPTFC_DRIVER &&
1574 ioc->bus_type != FC) ||
1575 (MptDriverClass[index] == MPTSAS_DRIVER &&
1576 ioc->bus_type != SAS))
1577 /* make sure we only call the relevant reset handler
1580 return (MptResetHandlers[index])(ioc, reset_phase);
1583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1585 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1586 * @ioc: Pointer to MPT adapter structure
1587 * @reason: Event word / reason
1588 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1590 * This routine performs all the steps necessary to bring the IOC
1591 * to a OPERATIONAL state.
1593 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1598 * -1 if failed to get board READY
1599 * -2 if READY but IOCFacts Failed
1600 * -3 if READY but PrimeIOCFifos Failed
1601 * -4 if READY but IOCInit Failed
1604 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1606 int hard_reset_done = 0;
1607 int alt_ioc_ready = 0;
1613 int reset_alt_ioc_active = 0;
1614 int irq_allocated = 0;
1616 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1617 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1619 /* Disable reply interrupts (also blocks FreeQ) */
1620 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1624 if (ioc->alt_ioc->active)
1625 reset_alt_ioc_active = 1;
1627 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1628 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1629 ioc->alt_ioc->active = 0;
1633 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1636 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1637 if (hard_reset_done == -4) {
1638 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1641 if (reset_alt_ioc_active && ioc->alt_ioc) {
1642 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1643 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1644 ioc->alt_ioc->name));
1645 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1646 ioc->alt_ioc->active = 1;
1650 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1656 /* hard_reset_done = 0 if a soft reset was performed
1657 * and 1 if a hard reset was performed.
1659 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1660 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1663 printk(KERN_WARNING MYNAM
1664 ": alt-%s: Not ready WARNING!\n",
1665 ioc->alt_ioc->name);
1668 for (ii=0; ii<5; ii++) {
1669 /* Get IOC facts! Allow 5 retries */
1670 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1676 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1678 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1679 MptDisplayIocCapabilities(ioc);
1682 if (alt_ioc_ready) {
1683 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1684 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1685 /* Retry - alt IOC was initialized once
1687 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1690 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1692 reset_alt_ioc_active = 0;
1693 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1694 MptDisplayIocCapabilities(ioc->alt_ioc);
1699 * Device is reset now. It must have de-asserted the interrupt line
1700 * (if it was asserted) and it should be safe to register for the
1703 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1705 if (ioc->pcidev->irq) {
1706 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1707 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1709 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1710 IRQF_SHARED, ioc->name, ioc);
1712 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1713 "interrupt %d!\n", ioc->name,
1716 pci_disable_msi(ioc->pcidev);
1720 ioc->pci_irq = ioc->pcidev->irq;
1721 pci_set_master(ioc->pcidev); /* ?? */
1722 pci_set_drvdata(ioc->pcidev, ioc);
1723 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1724 "%d\n", ioc->name, ioc->pcidev->irq));
1728 /* Prime reply & request queues!
1729 * (mucho alloc's) Must be done prior to
1730 * init as upper addresses are needed for init.
1731 * If fails, continue with alt-ioc processing
1733 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1736 /* May need to check/upload firmware & data here!
1737 * If fails, continue with alt-ioc processing
1739 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1742 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1743 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1744 ioc->alt_ioc->name, rc);
1746 reset_alt_ioc_active = 0;
1749 if (alt_ioc_ready) {
1750 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1752 reset_alt_ioc_active = 0;
1753 printk(KERN_WARNING MYNAM
1754 ": alt-%s: (%d) init failure WARNING!\n",
1755 ioc->alt_ioc->name, rc);
1759 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1760 if (ioc->upload_fw) {
1761 ddlprintk((MYIOC_s_INFO_FMT
1762 "firmware upload required!\n", ioc->name));
1764 /* Controller is not operational, cannot do upload
1767 rc = mpt_do_upload(ioc, sleepFlag);
1769 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1771 * Maintain only one pointer to FW memory
1772 * so there will not be two attempt to
1773 * downloadboot onboard dual function
1774 * chips (mpt_adapter_disable,
1777 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1778 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1779 ioc->alt_ioc->cached_fw = NULL;
1782 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1790 /* Enable! (reply interrupt) */
1791 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1795 if (reset_alt_ioc_active && ioc->alt_ioc) {
1796 /* (re)Enable alt-IOC! (reply interrupt) */
1797 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1798 ioc->alt_ioc->name));
1799 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1800 ioc->alt_ioc->active = 1;
1803 /* Enable MPT base driver management of EventNotification
1804 * and EventAck handling.
1806 if ((ret == 0) && (!ioc->facts.EventState))
1807 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1809 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1810 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1812 /* Add additional "reason" check before call to GetLanConfigPages
1813 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1814 * recursive scenario; GetLanConfigPages times out, timer expired
1815 * routine calls HardResetHandler, which calls into here again,
1816 * and we try GetLanConfigPages again...
1818 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1821 * Initalize link list for inactive raid volumes.
1823 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
1824 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
1826 if (ioc->bus_type == SAS) {
1828 /* clear persistency table */
1829 if(ioc->facts.IOCExceptions &
1830 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1831 ret = mptbase_sas_persist_operation(ioc,
1832 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1839 mpt_findImVolumes(ioc);
1841 } else if (ioc->bus_type == FC) {
1842 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1843 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1845 * Pre-fetch the ports LAN MAC address!
1846 * (LANPage1_t stuff)
1848 (void) GetLanConfigPages(ioc);
1851 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1852 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1853 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1858 /* Get NVRAM and adapter maximums from SPP 0 and 2
1860 mpt_GetScsiPortSettings(ioc, 0);
1862 /* Get version and length of SDP 1
1864 mpt_readScsiDevicePageHeaders(ioc, 0);
1868 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1869 mpt_findImVolumes(ioc);
1871 /* Check, and possibly reset, the coalescing value
1873 mpt_read_ioc_pg_1(ioc);
1875 mpt_read_ioc_pg_4(ioc);
1878 GetIoUnitPage2(ioc);
1882 * Call each currently registered protocol IOC reset handler
1883 * with post-reset indication.
1884 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1885 * MptResetHandlers[] registered yet.
1887 if (hard_reset_done) {
1889 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1890 if ((ret == 0) && MptResetHandlers[ii]) {
1891 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1893 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
1897 if (alt_ioc_ready && MptResetHandlers[ii]) {
1898 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1899 ioc->name, ioc->alt_ioc->name, ii));
1900 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
1904 /* FIXME? Examine results here? */
1908 if ((ret != 0) && irq_allocated) {
1909 free_irq(ioc->pci_irq, ioc);
1911 pci_disable_msi(ioc->pcidev);
1916 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1918 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
1919 * @ioc: Pointer to MPT adapter structure
1920 * @pdev: Pointer to (struct pci_dev) structure
1922 * Search for PCI bus/dev_function which matches
1923 * PCI bus/dev_function (+/-1) for newly discovered 929,
1924 * 929X, 1030 or 1035.
1926 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1927 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1930 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1932 struct pci_dev *peer=NULL;
1933 unsigned int slot = PCI_SLOT(pdev->devfn);
1934 unsigned int func = PCI_FUNC(pdev->devfn);
1935 MPT_ADAPTER *ioc_srch;
1937 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1938 " searching for devfn match on %x or %x\n",
1939 ioc->name, pci_name(pdev), pdev->bus->number,
1940 pdev->devfn, func-1, func+1));
1942 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1944 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1949 list_for_each_entry(ioc_srch, &ioc_list, list) {
1950 struct pci_dev *_pcidev = ioc_srch->pcidev;
1951 if (_pcidev == peer) {
1952 /* Paranoia checks */
1953 if (ioc->alt_ioc != NULL) {
1954 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1955 ioc->name, ioc->alt_ioc->name);
1957 } else if (ioc_srch->alt_ioc != NULL) {
1958 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1959 ioc_srch->name, ioc_srch->alt_ioc->name);
1962 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1963 ioc->name, ioc_srch->name));
1964 ioc_srch->alt_ioc = ioc;
1965 ioc->alt_ioc = ioc_srch;
1971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1973 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1974 * @ioc: Pointer to MPT adapter structure
1977 mpt_adapter_disable(MPT_ADAPTER *ioc)
1982 if (ioc->cached_fw != NULL) {
1983 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1984 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1985 printk(KERN_WARNING MYNAM
1986 ": firmware downloadboot failure (%d)!\n", ret);
1990 /* Disable adapter interrupts! */
1991 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1993 /* Clear any lingering interrupt */
1994 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1996 if (ioc->alloc != NULL) {
1998 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1999 ioc->name, ioc->alloc, ioc->alloc_sz));
2000 pci_free_consistent(ioc->pcidev, sz,
2001 ioc->alloc, ioc->alloc_dma);
2002 ioc->reply_frames = NULL;
2003 ioc->req_frames = NULL;
2005 ioc->alloc_total -= sz;
2008 if (ioc->sense_buf_pool != NULL) {
2009 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2010 pci_free_consistent(ioc->pcidev, sz,
2011 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2012 ioc->sense_buf_pool = NULL;
2013 ioc->alloc_total -= sz;
2016 if (ioc->events != NULL){
2017 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2020 ioc->alloc_total -= sz;
2023 if (ioc->cached_fw != NULL) {
2024 sz = ioc->facts.FWImageSize;
2025 pci_free_consistent(ioc->pcidev, sz,
2026 ioc->cached_fw, ioc->cached_fw_dma);
2027 ioc->cached_fw = NULL;
2028 ioc->alloc_total -= sz;
2031 kfree(ioc->spi_data.nvram);
2032 mpt_inactive_raid_list_free(ioc);
2033 kfree(ioc->raid_data.pIocPg2);
2034 kfree(ioc->raid_data.pIocPg3);
2035 ioc->spi_data.nvram = NULL;
2036 ioc->raid_data.pIocPg3 = NULL;
2038 if (ioc->spi_data.pIocPg4 != NULL) {
2039 sz = ioc->spi_data.IocPg4Sz;
2040 pci_free_consistent(ioc->pcidev, sz,
2041 ioc->spi_data.pIocPg4,
2042 ioc->spi_data.IocPg4_dma);
2043 ioc->spi_data.pIocPg4 = NULL;
2044 ioc->alloc_total -= sz;
2047 if (ioc->ReqToChain != NULL) {
2048 kfree(ioc->ReqToChain);
2049 kfree(ioc->RequestNB);
2050 ioc->ReqToChain = NULL;
2053 kfree(ioc->ChainToChain);
2054 ioc->ChainToChain = NULL;
2056 if (ioc->HostPageBuffer != NULL) {
2057 if((ret = mpt_host_page_access_control(ioc,
2058 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2059 printk(KERN_ERR MYNAM
2060 ": %s: host page buffers free failed (%d)!\n",
2063 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2064 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2065 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2066 ioc->HostPageBuffer,
2067 ioc->HostPageBuffer_dma);
2068 ioc->HostPageBuffer = NULL;
2069 ioc->HostPageBuffer_sz = 0;
2070 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2076 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2077 * @ioc: Pointer to MPT adapter structure
2079 * This routine unregisters h/w resources and frees all alloc'd memory
2080 * associated with a MPT adapter structure.
2083 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2085 int sz_first, sz_last;
2090 sz_first = ioc->alloc_total;
2092 mpt_adapter_disable(ioc);
2094 if (ioc->pci_irq != -1) {
2095 free_irq(ioc->pci_irq, ioc);
2097 pci_disable_msi(ioc->pcidev);
2101 if (ioc->memmap != NULL) {
2102 iounmap(ioc->memmap);
2106 #if defined(CONFIG_MTRR) && 0
2107 if (ioc->mtrr_reg > 0) {
2108 mtrr_del(ioc->mtrr_reg, 0, 0);
2109 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2113 /* Zap the adapter lookup ptr! */
2114 list_del(&ioc->list);
2116 sz_last = ioc->alloc_total;
2117 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2118 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2121 ioc->alt_ioc->alt_ioc = NULL;
2126 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2128 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2129 * @ioc: Pointer to MPT adapter structure
2132 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2136 printk(KERN_INFO "%s: ", ioc->name);
2137 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2138 printk("%s: ", ioc->prod_name+3);
2139 printk("Capabilities={");
2141 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2142 printk("Initiator");
2146 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2147 printk("%sTarget", i ? "," : "");
2151 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2152 printk("%sLAN", i ? "," : "");
2158 * This would probably evoke more questions than it's worth
2160 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2161 printk("%sLogBusAddr", i ? "," : "");
2169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2171 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2172 * @ioc: Pointer to MPT_ADAPTER structure
2173 * @force: Force hard KickStart of IOC
2174 * @sleepFlag: Specifies whether the process can sleep
2177 * 1 - DIAG reset and READY
2178 * 0 - READY initially OR soft reset and READY
2179 * -1 - Any failure on KickStart
2180 * -2 - Msg Unit Reset Failed
2181 * -3 - IO Unit Reset Failed
2182 * -4 - IOC owned by a PEER
2185 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2190 int hard_reset_done = 0;
2195 /* Get current [raw] IOC state */
2196 ioc_state = mpt_GetIocState(ioc, 0);
2197 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2200 * Check to see if IOC got left/stuck in doorbell handshake
2201 * grip of death. If so, hard reset the IOC.
2203 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2205 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2209 /* Is it already READY? */
2210 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2214 * Check to see if IOC is in FAULT state.
2216 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2218 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2220 printk(KERN_WARNING " FAULT code = %04xh\n",
2221 ioc_state & MPI_DOORBELL_DATA_MASK);
2225 * Hmmm... Did it get left operational?
2227 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2228 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2232 * If PCI Peer, exit.
2233 * Else, if no fault conditions are present, issue a MessageUnitReset
2234 * Else, fall through to KickStart case
2236 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2237 dinitprintk((KERN_INFO MYNAM
2238 ": whoinit 0x%x statefault %d force %d\n",
2239 whoinit, statefault, force));
2240 if (whoinit == MPI_WHOINIT_PCI_PEER)
2243 if ((statefault == 0 ) && (force == 0)) {
2244 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2251 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2252 if (hard_reset_done < 0)
2256 * Loop here waiting for IOC to come READY.
2259 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2261 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2262 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2264 * BIOS or previous driver load left IOC in OP state.
2265 * Reset messaging FIFOs.
2267 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2268 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2271 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2273 * Something is wrong. Try to get IOC back
2276 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2277 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2284 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2285 ioc->name, (int)((ii+5)/HZ));
2289 if (sleepFlag == CAN_SLEEP) {
2292 mdelay (1); /* 1 msec delay */
2297 if (statefault < 3) {
2298 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2300 statefault==1 ? "stuck handshake" : "IOC FAULT");
2303 return hard_reset_done;
2306 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2308 * mpt_GetIocState - Get the current state of a MPT adapter.
2309 * @ioc: Pointer to MPT_ADAPTER structure
2310 * @cooked: Request raw or cooked IOC state
2312 * Returns all IOC Doorbell register bits if cooked==0, else just the
2313 * Doorbell bits in MPI_IOC_STATE_MASK.
2316 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2321 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2322 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2323 sc = s & MPI_IOC_STATE_MASK;
2326 ioc->last_state = sc;
2328 return cooked ? sc : s;
2331 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2333 * GetIocFacts - Send IOCFacts request to MPT adapter.
2334 * @ioc: Pointer to MPT_ADAPTER structure
2335 * @sleepFlag: Specifies whether the process can sleep
2336 * @reason: If recovery, only update facts.
2338 * Returns 0 for success, non-zero for failure.
2341 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2343 IOCFacts_t get_facts;
2344 IOCFactsReply_t *facts;
2352 /* IOC *must* NOT be in RESET state! */
2353 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2354 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2360 facts = &ioc->facts;
2362 /* Destination (reply area)... */
2363 reply_sz = sizeof(*facts);
2364 memset(facts, 0, reply_sz);
2366 /* Request area (get_facts on the stack right now!) */
2367 req_sz = sizeof(get_facts);
2368 memset(&get_facts, 0, req_sz);
2370 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2371 /* Assert: All other get_facts fields are zero! */
2373 dinitprintk((MYIOC_s_INFO_FMT
2374 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2375 ioc->name, req_sz, reply_sz));
2377 /* No non-zero fields in the get_facts request are greater than
2378 * 1 byte in size, so we can just fire it off as is.
2380 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2381 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2386 * Now byte swap (GRRR) the necessary fields before any further
2387 * inspection of reply contents.
2389 * But need to do some sanity checks on MsgLength (byte) field
2390 * to make sure we don't zero IOC's req_sz!
2392 /* Did we get a valid reply? */
2393 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2394 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2396 * If not been here, done that, save off first WhoInit value
2398 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2399 ioc->FirstWhoInit = facts->WhoInit;
2402 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2403 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2404 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2405 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2406 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2407 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2408 /* CHECKME! IOCStatus, IOCLogInfo */
2410 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2411 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2414 * FC f/w version changed between 1.1 and 1.2
2415 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2416 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2418 if (facts->MsgVersion < 0x0102) {
2420 * Handle old FC f/w style, convert to new...
2422 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2423 facts->FWVersion.Word =
2424 ((oldv<<12) & 0xFF000000) |
2425 ((oldv<<8) & 0x000FFF00);
2427 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2429 facts->ProductID = le16_to_cpu(facts->ProductID);
2430 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2431 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2432 ioc->ir_firmware = 1;
2433 facts->CurrentHostMfaHighAddr =
2434 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2435 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2436 facts->CurrentSenseBufferHighAddr =
2437 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2438 facts->CurReplyFrameSize =
2439 le16_to_cpu(facts->CurReplyFrameSize);
2440 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2443 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2444 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2445 * to 14 in MPI-1.01.0x.
2447 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2448 facts->MsgVersion > 0x0100) {
2449 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2452 sz = facts->FWImageSize;
2457 facts->FWImageSize = sz;
2459 if (!facts->RequestFrameSize) {
2460 /* Something is wrong! */
2461 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2466 r = sz = facts->BlockSize;
2467 vv = ((63 / (sz * 4)) + 1) & 0x03;
2468 ioc->NB_for_64_byte_frame = vv;
2474 ioc->NBShiftFactor = shiftFactor;
2475 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2476 ioc->name, vv, shiftFactor, r));
2478 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2480 * Set values for this IOC's request & reply frame sizes,
2481 * and request & reply queue depths...
2483 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2484 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2485 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2486 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2488 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2489 ioc->name, ioc->reply_sz, ioc->reply_depth));
2490 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2491 ioc->name, ioc->req_sz, ioc->req_depth));
2493 /* Get port facts! */
2494 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2498 printk(MYIOC_s_ERR_FMT
2499 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2500 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2501 RequestFrameSize)/sizeof(u32)));
2508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2510 * GetPortFacts - Send PortFacts request to MPT adapter.
2511 * @ioc: Pointer to MPT_ADAPTER structure
2512 * @portnum: Port number
2513 * @sleepFlag: Specifies whether the process can sleep
2515 * Returns 0 for success, non-zero for failure.
2518 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2520 PortFacts_t get_pfacts;
2521 PortFactsReply_t *pfacts;
2527 /* IOC *must* NOT be in RESET state! */
2528 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2529 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2535 pfacts = &ioc->pfacts[portnum];
2537 /* Destination (reply area)... */
2538 reply_sz = sizeof(*pfacts);
2539 memset(pfacts, 0, reply_sz);
2541 /* Request area (get_pfacts on the stack right now!) */
2542 req_sz = sizeof(get_pfacts);
2543 memset(&get_pfacts, 0, req_sz);
2545 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2546 get_pfacts.PortNumber = portnum;
2547 /* Assert: All other get_pfacts fields are zero! */
2549 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2550 ioc->name, portnum));
2552 /* No non-zero fields in the get_pfacts request are greater than
2553 * 1 byte in size, so we can just fire it off as is.
2555 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2556 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2560 /* Did we get a valid reply? */
2562 /* Now byte swap the necessary fields in the response. */
2563 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2564 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2565 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2566 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2567 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2568 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2569 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2570 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2571 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2573 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2575 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2576 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2579 * Place all the devices on channels
2583 if (mpt_channel_mapping) {
2584 ioc->devices_per_bus = 1;
2585 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2591 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2593 * SendIocInit - Send IOCInit request to MPT adapter.
2594 * @ioc: Pointer to MPT_ADAPTER structure
2595 * @sleepFlag: Specifies whether the process can sleep
2597 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2599 * Returns 0 for success, non-zero for failure.
2602 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2605 MPIDefaultReply_t init_reply;
2611 memset(&ioc_init, 0, sizeof(ioc_init));
2612 memset(&init_reply, 0, sizeof(init_reply));
2614 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2615 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2617 /* If we are in a recovery mode and we uploaded the FW image,
2618 * then this pointer is not NULL. Skip the upload a second time.
2619 * Set this flag if cached_fw set for either IOC.
2621 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2625 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2626 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2628 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2629 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2630 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2631 ioc->name, ioc->facts.MsgVersion));
2632 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2633 // set MsgVersion and HeaderVersion host driver was built with
2634 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2635 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2637 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2638 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2639 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2642 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2644 if (sizeof(dma_addr_t) == sizeof(u64)) {
2645 /* Save the upper 32-bits of the request
2646 * (reply) and sense buffers.
2648 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2649 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2651 /* Force 32-bit addressing */
2652 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2653 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2656 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2657 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2658 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2659 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2661 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2662 ioc->name, &ioc_init));
2664 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2665 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2667 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2671 /* No need to byte swap the multibyte fields in the reply
2672 * since we don't even look at its contents.
2675 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2676 ioc->name, &ioc_init));
2678 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2679 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2683 /* YIKES! SUPER IMPORTANT!!!
2684 * Poll IocState until _OPERATIONAL while IOC is doing
2685 * LoopInit and TargetDiscovery!
2688 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2689 state = mpt_GetIocState(ioc, 1);
2690 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2691 if (sleepFlag == CAN_SLEEP) {
2698 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2699 ioc->name, (int)((count+5)/HZ));
2703 state = mpt_GetIocState(ioc, 1);
2706 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2709 ioc->aen_event_read_flag=0;
2713 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2715 * SendPortEnable - Send PortEnable request to MPT adapter port.
2716 * @ioc: Pointer to MPT_ADAPTER structure
2717 * @portnum: Port number to enable
2718 * @sleepFlag: Specifies whether the process can sleep
2720 * Send PortEnable to bring IOC to OPERATIONAL state.
2722 * Returns 0 for success, non-zero for failure.
2725 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2727 PortEnable_t port_enable;
2728 MPIDefaultReply_t reply_buf;
2733 /* Destination... */
2734 reply_sz = sizeof(MPIDefaultReply_t);
2735 memset(&reply_buf, 0, reply_sz);
2737 req_sz = sizeof(PortEnable_t);
2738 memset(&port_enable, 0, req_sz);
2740 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2741 port_enable.PortNumber = portnum;
2742 /* port_enable.ChainOffset = 0; */
2743 /* port_enable.MsgFlags = 0; */
2744 /* port_enable.MsgContext = 0; */
2746 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2747 ioc->name, portnum, &port_enable));
2749 /* RAID FW may take a long time to enable
2751 if (ioc->ir_firmware || ioc->bus_type == SAS) {
2752 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2753 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2754 300 /*seconds*/, sleepFlag);
2756 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2757 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2758 30 /*seconds*/, sleepFlag);
2764 * mpt_alloc_fw_memory - allocate firmware memory
2765 * @ioc: Pointer to MPT_ADAPTER structure
2766 * @size: total FW bytes
2768 * If memory has already been allocated, the same (cached) value
2772 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2775 return; /* use already allocated memory */
2776 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2777 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2778 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2779 ioc->alloc_total += size;
2780 ioc->alt_ioc->alloc_total -= size;
2782 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2783 ioc->alloc_total += size;
2787 * mpt_free_fw_memory - free firmware memory
2788 * @ioc: Pointer to MPT_ADAPTER structure
2790 * If alt_img is NULL, delete from ioc structure.
2791 * Else, delete a secondary image in same format.
2794 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2798 sz = ioc->facts.FWImageSize;
2799 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2800 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2801 pci_free_consistent(ioc->pcidev, sz,
2802 ioc->cached_fw, ioc->cached_fw_dma);
2803 ioc->cached_fw = NULL;
2809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2811 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2812 * @ioc: Pointer to MPT_ADAPTER structure
2813 * @sleepFlag: Specifies whether the process can sleep
2815 * Returns 0 for success, >0 for handshake failure
2816 * <0 for fw upload failure.
2818 * Remark: If bound IOC and a successful FWUpload was performed
2819 * on the bound IOC, the second image is discarded
2820 * and memory is free'd. Both channels must upload to prevent
2821 * IOC from running in degraded mode.
2824 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2826 u8 request[ioc->req_sz];
2827 u8 reply[sizeof(FWUploadReply_t)];
2828 FWUpload_t *prequest;
2829 FWUploadReply_t *preply;
2830 FWUploadTCSGE_t *ptcsge;
2833 int ii, sz, reply_sz;
2836 /* If the image size is 0, we are done.
2838 if ((sz = ioc->facts.FWImageSize) == 0)
2841 mpt_alloc_fw_memory(ioc, sz);
2843 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2844 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2846 if (ioc->cached_fw == NULL) {
2852 prequest = (FWUpload_t *)&request;
2853 preply = (FWUploadReply_t *)&reply;
2855 /* Destination... */
2856 memset(prequest, 0, ioc->req_sz);
2858 reply_sz = sizeof(reply);
2859 memset(preply, 0, reply_sz);
2861 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2862 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2864 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2865 ptcsge->DetailsLength = 12;
2866 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2867 ptcsge->ImageSize = cpu_to_le32(sz);
2869 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2871 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2872 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2874 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2875 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2876 prequest, sgeoffset));
2877 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2879 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2880 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2882 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2884 cmdStatus = -EFAULT;
2886 /* Handshake transfer was complete and successful.
2887 * Check the Reply Frame.
2889 int status, transfer_sz;
2890 status = le16_to_cpu(preply->IOCStatus);
2891 if (status == MPI_IOCSTATUS_SUCCESS) {
2892 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2893 if (transfer_sz == sz)
2897 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2898 ioc->name, cmdStatus));
2903 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2905 mpt_free_fw_memory(ioc);
2911 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2913 * mpt_downloadboot - DownloadBoot code
2914 * @ioc: Pointer to MPT_ADAPTER structure
2915 * @pFwHeader: Pointer to firmware header info
2916 * @sleepFlag: Specifies whether the process can sleep
2918 * FwDownloadBoot requires Programmed IO access.
2920 * Returns 0 for success
2921 * -1 FW Image size is 0
2922 * -2 No valid cached_fw Pointer
2923 * <0 for fw upload failure.
2926 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2928 MpiExtImageHeader_t *pExtImage;
2938 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2939 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2941 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2942 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2943 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2944 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2945 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2946 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2948 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2951 if (sleepFlag == CAN_SLEEP) {
2957 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2958 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2960 for (count = 0; count < 30; count ++) {
2961 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2962 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2963 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2968 if (sleepFlag == CAN_SLEEP) {
2975 if ( count == 30 ) {
2976 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2977 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2978 ioc->name, diag0val));
2982 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2983 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2984 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2985 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2986 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2987 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2989 /* Set the DiagRwEn and Disable ARM bits */
2990 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2992 fwSize = (pFwHeader->ImageSize + 3)/4;
2993 ptrFw = (u32 *) pFwHeader;
2995 /* Write the LoadStartAddress to the DiagRw Address Register
2996 * using Programmed IO
2998 if (ioc->errata_flag_1064)
2999 pci_enable_io_access(ioc->pcidev);
3001 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3002 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
3003 ioc->name, pFwHeader->LoadStartAddress));
3005 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
3006 ioc->name, fwSize*4, ptrFw));
3008 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3011 nextImage = pFwHeader->NextImageHeaderOffset;
3013 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3015 load_addr = pExtImage->LoadStartAddress;
3017 fwSize = (pExtImage->ImageSize + 3) >> 2;
3018 ptrFw = (u32 *)pExtImage;
3020 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3021 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3022 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3025 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3027 nextImage = pExtImage->NextImageHeaderOffset;
3030 /* Write the IopResetVectorRegAddr */
3031 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3032 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3034 /* Write the IopResetVectorValue */
3035 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3036 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3038 /* Clear the internal flash bad bit - autoincrementing register,
3039 * so must do two writes.
3041 if (ioc->bus_type == SPI) {
3043 * 1030 and 1035 H/W errata, workaround to access
3044 * the ClearFlashBadSignatureBit
3046 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3047 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3048 diagRwData |= 0x40000000;
3049 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3050 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3052 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3053 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3054 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3055 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3058 if (sleepFlag == CAN_SLEEP) {
3065 if (ioc->errata_flag_1064)
3066 pci_disable_io_access(ioc->pcidev);
3068 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3069 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3070 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3071 ioc->name, diag0val));
3072 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3073 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3074 ioc->name, diag0val));
3075 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3077 /* Write 0xFF to reset the sequencer */
3078 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3080 if (ioc->bus_type == SAS) {
3081 ioc_state = mpt_GetIocState(ioc, 0);
3082 if ( (GetIocFacts(ioc, sleepFlag,
3083 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3084 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3085 ioc->name, ioc_state));
3090 for (count=0; count<HZ*20; count++) {
3091 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3092 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3093 ioc->name, count, ioc_state));
3094 if (ioc->bus_type == SAS) {
3097 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3098 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3102 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3106 if (sleepFlag == CAN_SLEEP) {
3112 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3113 ioc->name, ioc_state));
3117 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3119 * KickStart - Perform hard reset of MPT adapter.
3120 * @ioc: Pointer to MPT_ADAPTER structure
3121 * @force: Force hard reset
3122 * @sleepFlag: Specifies whether the process can sleep
3124 * This routine places MPT adapter in diagnostic mode via the
3125 * WriteSequence register, and then performs a hard reset of adapter
3126 * via the Diagnostic register.
3128 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3129 * or NO_SLEEP (interrupt thread, use mdelay)
3130 * force - 1 if doorbell active, board fault state
3131 * board operational, IOC_RECOVERY or
3132 * IOC_BRINGUP and there is an alt_ioc.
3136 * 1 - hard reset, READY
3137 * 0 - no reset due to History bit, READY
3138 * -1 - no reset due to History bit but not READY
3139 * OR reset but failed to come READY
3140 * -2 - no reset, could not enter DIAG mode
3141 * -3 - reset but bad FW bit
3144 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3146 int hard_reset_done = 0;
3150 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3151 if (ioc->bus_type == SPI) {
3152 /* Always issue a Msg Unit Reset first. This will clear some
3153 * SCSI bus hang conditions.
3155 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3157 if (sleepFlag == CAN_SLEEP) {
3164 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3165 if (hard_reset_done < 0)
3166 return hard_reset_done;
3168 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3171 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3172 for (cnt=0; cnt<cntdn; cnt++) {
3173 ioc_state = mpt_GetIocState(ioc, 1);
3174 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3175 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3177 return hard_reset_done;
3179 if (sleepFlag == CAN_SLEEP) {
3186 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3187 ioc->name, ioc_state);
3191 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3193 * mpt_diag_reset - Perform hard reset of the adapter.
3194 * @ioc: Pointer to MPT_ADAPTER structure
3195 * @ignore: Set if to honor and clear to ignore
3196 * the reset history bit
3197 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3198 * else set to NO_SLEEP (use mdelay instead)
3200 * This routine places the adapter in diagnostic mode via the
3201 * WriteSequence register and then performs a hard reset of adapter
3202 * via the Diagnostic register. Adapter should be in ready state
3203 * upon successful completion.
3205 * Returns: 1 hard reset successful
3206 * 0 no reset performed because reset history bit set
3207 * -2 enabling diagnostic mode failed
3208 * -3 diagnostic reset failed
3211 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3213 MPT_ADAPTER *iocp=NULL;
3216 int hard_reset_done = 0;
3222 /* Clear any existing interrupts */
3223 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3225 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3226 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3227 "address=%p\n", ioc->name, __FUNCTION__,
3228 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3229 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3230 if (sleepFlag == CAN_SLEEP)
3235 for (count = 0; count < 60; count ++) {
3236 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3237 doorbell &= MPI_IOC_STATE_MASK;
3239 drsprintk((MYIOC_s_INFO_FMT
3240 "looking for READY STATE: doorbell=%x"
3242 ioc->name, doorbell, count));
3243 if (doorbell == MPI_IOC_STATE_READY) {
3248 if (sleepFlag == CAN_SLEEP)
3256 /* Use "Diagnostic reset" method! (only thing available!) */
3257 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3261 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3262 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3263 ioc->name, diag0val, diag1val));
3266 /* Do the reset if we are told to ignore the reset history
3267 * or if the reset history is 0
3269 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3270 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3271 /* Write magic sequence to WriteSequence register
3272 * Loop until in diagnostic mode
3274 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3275 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3276 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3277 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3278 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3279 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3282 if (sleepFlag == CAN_SLEEP) {
3290 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3291 ioc->name, diag0val);
3296 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3298 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3299 ioc->name, diag0val));
3304 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3305 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3306 ioc->name, diag0val, diag1val));
3309 * Disable the ARM (Bug fix)
3312 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3316 * Now hit the reset bit in the Diagnostic register
3317 * (THE BIG HAMMER!) (Clears DRWE bit).
3319 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3320 hard_reset_done = 1;
3321 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3325 * Call each currently registered protocol IOC reset handler
3326 * with pre-reset indication.
3327 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3328 * MptResetHandlers[] registered yet.
3334 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3335 if (MptResetHandlers[ii]) {
3336 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3338 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3340 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3341 ioc->name, ioc->alt_ioc->name, ii));
3342 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3346 /* FIXME? Examine results here? */
3351 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3352 iocp = ioc->alt_ioc;
3354 /* If the DownloadBoot operation fails, the
3355 * IOC will be left unusable. This is a fatal error
3356 * case. _diag_reset will return < 0
3358 for (count = 0; count < 30; count ++) {
3359 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3360 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3364 dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
3365 iocp->name, diag0val, count));
3367 if (sleepFlag == CAN_SLEEP) {
3373 if ((count = mpt_downloadboot(ioc,
3374 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3375 printk(KERN_WARNING MYNAM
3376 ": firmware downloadboot failure (%d)!\n", count);
3380 /* Wait for FW to reload and for board
3381 * to go to the READY state.
3382 * Maximum wait is 60 seconds.
3383 * If fail, no error will check again
3384 * with calling program.
3386 for (count = 0; count < 60; count ++) {
3387 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3388 doorbell &= MPI_IOC_STATE_MASK;
3390 if (doorbell == MPI_IOC_STATE_READY) {
3395 if (sleepFlag == CAN_SLEEP) {
3404 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3407 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3408 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3409 ioc->name, diag0val, diag1val));
3412 /* Clear RESET_HISTORY bit! Place board in the
3413 * diagnostic mode to update the diag register.
3415 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3417 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3418 /* Write magic sequence to WriteSequence register
3419 * Loop until in diagnostic mode
3421 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3422 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3423 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3424 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3425 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3426 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3429 if (sleepFlag == CAN_SLEEP) {
3437 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3438 ioc->name, diag0val);
3441 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3443 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3444 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3445 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3446 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3447 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3451 /* Disable Diagnostic Mode
3453 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3455 /* Check FW reload status flags.
3457 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3458 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3459 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3460 ioc->name, diag0val);
3466 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3467 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3468 ioc->name, diag0val, diag1val));
3472 * Reset flag that says we've enabled event notification
3474 ioc->facts.EventState = 0;
3477 ioc->alt_ioc->facts.EventState = 0;
3479 return hard_reset_done;
3482 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3484 * SendIocReset - Send IOCReset request to MPT adapter.
3485 * @ioc: Pointer to MPT_ADAPTER structure
3486 * @reset_type: reset type, expected values are
3487 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3488 * @sleepFlag: Specifies whether the process can sleep
3490 * Send IOCReset request to the MPT adapter.
3492 * Returns 0 for success, non-zero for failure.
3495 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3501 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3502 ioc->name, reset_type));
3503 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3504 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3507 /* FW ACK'd request, wait for READY state
3510 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3512 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3516 if (sleepFlag != CAN_SLEEP)
3519 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3520 ioc->name, (int)((count+5)/HZ));
3524 if (sleepFlag == CAN_SLEEP) {
3527 mdelay (1); /* 1 msec delay */
3532 * Cleanup all event stuff for this IOC; re-issue EventNotification
3533 * request if needed.
3535 if (ioc->facts.Function)
3536 ioc->facts.EventState = 0;
3541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3543 * initChainBuffers - Allocate memory for and initialize chain buffers
3544 * @ioc: Pointer to MPT_ADAPTER structure
3546 * Allocates memory for and initializes chain buffers,
3547 * chain buffer control arrays and spinlock.
3550 initChainBuffers(MPT_ADAPTER *ioc)
3553 int sz, ii, num_chain;
3554 int scale, num_sge, numSGE;
3556 /* ReqToChain size must equal the req_depth
3559 if (ioc->ReqToChain == NULL) {
3560 sz = ioc->req_depth * sizeof(int);
3561 mem = kmalloc(sz, GFP_ATOMIC);
3565 ioc->ReqToChain = (int *) mem;
3566 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3567 ioc->name, mem, sz));
3568 mem = kmalloc(sz, GFP_ATOMIC);
3572 ioc->RequestNB = (int *) mem;
3573 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3574 ioc->name, mem, sz));
3576 for (ii = 0; ii < ioc->req_depth; ii++) {
3577 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3580 /* ChainToChain size must equal the total number
3581 * of chain buffers to be allocated.
3584 * Calculate the number of chain buffers needed(plus 1) per I/O
3585 * then multiply the the maximum number of simultaneous cmds
3587 * num_sge = num sge in request frame + last chain buffer
3588 * scale = num sge per chain buffer if no chain element
3590 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3591 if (sizeof(dma_addr_t) == sizeof(u64))
3592 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3594 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3596 if (sizeof(dma_addr_t) == sizeof(u64)) {
3597 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3598 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3600 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3601 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3603 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3604 ioc->name, num_sge, numSGE));
3606 if ( numSGE > MPT_SCSI_SG_DEPTH )
3607 numSGE = MPT_SCSI_SG_DEPTH;
3610 while (numSGE - num_sge > 0) {
3612 num_sge += (scale - 1);
3616 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3617 ioc->name, numSGE, num_sge, num_chain));
3619 if (ioc->bus_type == SPI)
3620 num_chain *= MPT_SCSI_CAN_QUEUE;
3622 num_chain *= MPT_FC_CAN_QUEUE;
3624 ioc->num_chain = num_chain;
3626 sz = num_chain * sizeof(int);
3627 if (ioc->ChainToChain == NULL) {
3628 mem = kmalloc(sz, GFP_ATOMIC);
3632 ioc->ChainToChain = (int *) mem;
3633 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3634 ioc->name, mem, sz));
3636 mem = (u8 *) ioc->ChainToChain;
3638 memset(mem, 0xFF, sz);
3642 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3644 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3645 * @ioc: Pointer to MPT_ADAPTER structure
3647 * This routine allocates memory for the MPT reply and request frame
3648 * pools (if necessary), and primes the IOC reply FIFO with
3651 * Returns 0 for success, non-zero for failure.
3654 PrimeIocFifos(MPT_ADAPTER *ioc)
3657 unsigned long flags;
3658 dma_addr_t alloc_dma;
3660 int i, reply_sz, sz, total_size, num_chain;
3662 /* Prime reply FIFO... */
3664 if (ioc->reply_frames == NULL) {
3665 if ( (num_chain = initChainBuffers(ioc)) < 0)
3668 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3669 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3670 ioc->name, ioc->reply_sz, ioc->reply_depth));
3671 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3672 ioc->name, reply_sz, reply_sz));
3674 sz = (ioc->req_sz * ioc->req_depth);
3675 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3676 ioc->name, ioc->req_sz, ioc->req_depth));
3677 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3678 ioc->name, sz, sz));
3681 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3682 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3683 ioc->name, ioc->req_sz, num_chain));
3684 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3685 ioc->name, sz, sz, num_chain));
3688 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3690 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3695 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3696 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3698 memset(mem, 0, total_size);
3699 ioc->alloc_total += total_size;
3701 ioc->alloc_dma = alloc_dma;
3702 ioc->alloc_sz = total_size;
3703 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3704 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3706 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3707 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3709 alloc_dma += reply_sz;
3712 /* Request FIFO - WE manage this! */
3714 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3715 ioc->req_frames_dma = alloc_dma;
3717 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3718 ioc->name, mem, (void *)(ulong)alloc_dma));
3720 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3722 #if defined(CONFIG_MTRR) && 0
3724 * Enable Write Combining MTRR for IOC's memory region.
3725 * (at least as much as we can; "size and base must be
3726 * multiples of 4 kiB"
3728 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3730 MTRR_TYPE_WRCOMB, 1);
3731 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3732 ioc->name, ioc->req_frames_dma, sz));
3735 for (i = 0; i < ioc->req_depth; i++) {
3736 alloc_dma += ioc->req_sz;
3740 ioc->ChainBuffer = mem;
3741 ioc->ChainBufferDMA = alloc_dma;
3743 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3744 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3746 /* Initialize the free chain Q.
3749 INIT_LIST_HEAD(&ioc->FreeChainQ);
3751 /* Post the chain buffers to the FreeChainQ.
3753 mem = (u8 *)ioc->ChainBuffer;
3754 for (i=0; i < num_chain; i++) {
3755 mf = (MPT_FRAME_HDR *) mem;
3756 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3760 /* Initialize Request frames linked list
3762 alloc_dma = ioc->req_frames_dma;
3763 mem = (u8 *) ioc->req_frames;
3765 spin_lock_irqsave(&ioc->FreeQlock, flags);
3766 INIT_LIST_HEAD(&ioc->FreeQ);
3767 for (i = 0; i < ioc->req_depth; i++) {
3768 mf = (MPT_FRAME_HDR *) mem;
3770 /* Queue REQUESTs *internally*! */
3771 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3775 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3777 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3778 ioc->sense_buf_pool =
3779 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3780 if (ioc->sense_buf_pool == NULL) {
3781 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3786 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3787 ioc->alloc_total += sz;
3788 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3789 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3793 /* Post Reply frames to FIFO
3795 alloc_dma = ioc->alloc_dma;
3796 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3797 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3799 for (i = 0; i < ioc->reply_depth; i++) {
3800 /* Write each address to the IOC! */
3801 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3802 alloc_dma += ioc->reply_sz;
3808 if (ioc->alloc != NULL) {
3810 pci_free_consistent(ioc->pcidev,
3812 ioc->alloc, ioc->alloc_dma);
3813 ioc->reply_frames = NULL;
3814 ioc->req_frames = NULL;
3815 ioc->alloc_total -= sz;
3817 if (ioc->sense_buf_pool != NULL) {
3818 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3819 pci_free_consistent(ioc->pcidev,
3821 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3822 ioc->sense_buf_pool = NULL;
3827 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3829 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3830 * from IOC via doorbell handshake method.
3831 * @ioc: Pointer to MPT_ADAPTER structure
3832 * @reqBytes: Size of the request in bytes
3833 * @req: Pointer to MPT request frame
3834 * @replyBytes: Expected size of the reply in bytes
3835 * @u16reply: Pointer to area where reply should be written
3836 * @maxwait: Max wait time for a reply (in seconds)
3837 * @sleepFlag: Specifies whether the process can sleep
3839 * NOTES: It is the callers responsibility to byte-swap fields in the
3840 * request which are greater than 1 byte in size. It is also the
3841 * callers responsibility to byte-swap response fields which are
3842 * greater than 1 byte in size.
3844 * Returns 0 for success, non-zero for failure.
3847 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3848 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3850 MPIDefaultReply_t *mptReply;
3855 * Get ready to cache a handshake reply
3857 ioc->hs_reply_idx = 0;
3858 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3859 mptReply->MsgLength = 0;
3862 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3863 * then tell IOC that we want to handshake a request of N words.
3864 * (WRITE u32val to Doorbell reg).
3866 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3867 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3868 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3869 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3872 * Wait for IOC's doorbell handshake int
3874 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3877 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3878 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3880 /* Read doorbell and check for active bit */
3881 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3885 * Clear doorbell int (WRITE 0 to IntStatus reg),
3886 * then wait for IOC to ACKnowledge that it's ready for
3887 * our handshake request.
3889 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3890 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3895 u8 *req_as_bytes = (u8 *) req;
3898 * Stuff request words via doorbell handshake,
3899 * with ACK from IOC for each.
3901 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3902 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3903 (req_as_bytes[(ii*4) + 1] << 8) |
3904 (req_as_bytes[(ii*4) + 2] << 16) |
3905 (req_as_bytes[(ii*4) + 3] << 24));
3907 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3908 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3912 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3913 DBG_DUMP_REQUEST_FRAME_HDR(req)
3915 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3916 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3919 * Wait for completion of doorbell handshake reply from the IOC
3921 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3924 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3925 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3928 * Copy out the cached reply...
3930 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3931 u16reply[ii] = ioc->hs_reply[ii];
3939 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3941 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
3942 * @ioc: Pointer to MPT_ADAPTER structure
3943 * @howlong: How long to wait (in seconds)
3944 * @sleepFlag: Specifies whether the process can sleep
3946 * This routine waits (up to ~2 seconds max) for IOC doorbell
3947 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
3948 * bit in its IntStatus register being clear.
3950 * Returns a negative value on failure, else wait loop count.
3953 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3959 cntdn = 1000 * howlong;
3961 if (sleepFlag == CAN_SLEEP) {
3964 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3965 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3972 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3973 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3980 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3985 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3986 ioc->name, count, intstat);
3990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3992 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
3993 * @ioc: Pointer to MPT_ADAPTER structure
3994 * @howlong: How long to wait (in seconds)
3995 * @sleepFlag: Specifies whether the process can sleep
3997 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
3998 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4000 * Returns a negative value on failure, else wait loop count.
4003 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4009 cntdn = 1000 * howlong;
4010 if (sleepFlag == CAN_SLEEP) {
4012 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4013 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4020 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4021 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4029 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4030 ioc->name, count, howlong));
4034 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4035 ioc->name, count, intstat);
4039 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4041 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4042 * @ioc: Pointer to MPT_ADAPTER structure
4043 * @howlong: How long to wait (in seconds)
4044 * @sleepFlag: Specifies whether the process can sleep
4046 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4047 * Reply is cached to IOC private area large enough to hold a maximum
4048 * of 128 bytes of reply data.
4050 * Returns a negative value on failure, else size of reply in WORDS.
4053 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4058 u16 *hs_reply = ioc->hs_reply;
4059 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4062 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4065 * Get first two u16's so we can look at IOC's intended reply MsgLength
4068 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4071 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4072 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4073 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4076 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4077 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4081 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4082 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4083 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4086 * If no error (and IOC said MsgLength is > 0), piece together
4087 * reply 16 bits at a time.
4089 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4090 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4092 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4093 /* don't overflow our IOC hs_reply[] buffer! */
4094 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4095 hs_reply[u16cnt] = hword;
4096 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4099 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4101 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4104 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4109 else if (u16cnt != (2 * mptReply->MsgLength)) {
4112 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4117 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4118 DBG_DUMP_REPLY_FRAME(mptReply)
4120 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4121 ioc->name, t, u16cnt/2));
4125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4127 * GetLanConfigPages - Fetch LANConfig pages.
4128 * @ioc: Pointer to MPT_ADAPTER structure
4130 * Return: 0 for success
4131 * -ENOMEM if no memory available
4132 * -EPERM if not allowed due to ISR context
4133 * -EAGAIN if no msg frames currently available
4134 * -EFAULT for non-successful reply or no reply (timeout)
4137 GetLanConfigPages(MPT_ADAPTER *ioc)
4139 ConfigPageHeader_t hdr;
4141 LANPage0_t *ppage0_alloc;
4142 dma_addr_t page0_dma;
4143 LANPage1_t *ppage1_alloc;
4144 dma_addr_t page1_dma;
4149 /* Get LAN Page 0 header */
4150 hdr.PageVersion = 0;
4153 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4154 cfg.cfghdr.hdr = &hdr;
4156 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4161 if ((rc = mpt_config(ioc, &cfg)) != 0)
4164 if (hdr.PageLength > 0) {
4165 data_sz = hdr.PageLength * 4;
4166 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4169 memset((u8 *)ppage0_alloc, 0, data_sz);
4170 cfg.physAddr = page0_dma;
4171 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4173 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4175 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4176 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4180 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4183 * Normalize endianness of structure data,
4184 * by byte-swapping all > 1 byte fields!
4193 /* Get LAN Page 1 header */
4194 hdr.PageVersion = 0;
4197 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4198 cfg.cfghdr.hdr = &hdr;
4200 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4204 if ((rc = mpt_config(ioc, &cfg)) != 0)
4207 if (hdr.PageLength == 0)
4210 data_sz = hdr.PageLength * 4;
4212 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4214 memset((u8 *)ppage1_alloc, 0, data_sz);
4215 cfg.physAddr = page1_dma;
4216 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4218 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4220 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4221 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4224 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4227 * Normalize endianness of structure data,
4228 * by byte-swapping all > 1 byte fields!
4236 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4238 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4239 * @ioc: Pointer to MPT_ADAPTER structure
4240 * @persist_opcode: see below
4242 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4243 * devices not currently present.
4244 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4246 * NOTE: Don't use not this function during interrupt time.
4248 * Returns 0 for success, non-zero error
4251 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4253 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4255 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4256 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4257 MPT_FRAME_HDR *mf = NULL;
4258 MPIHeader_t *mpi_hdr;
4261 /* insure garbage is not sent to fw */
4262 switch(persist_opcode) {
4264 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4265 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4273 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4275 /* Get a MF for this command.
4277 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4278 printk("%s: no msg frames!\n",__FUNCTION__);
4282 mpi_hdr = (MPIHeader_t *) mf;
4283 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4284 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4285 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4286 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4287 sasIoUnitCntrReq->Operation = persist_opcode;
4289 init_timer(&ioc->persist_timer);
4290 ioc->persist_timer.data = (unsigned long) ioc;
4291 ioc->persist_timer.function = mpt_timer_expired;
4292 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4293 ioc->persist_wait_done=0;
4294 add_timer(&ioc->persist_timer);
4295 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4296 wait_event(mpt_waitq, ioc->persist_wait_done);
4298 sasIoUnitCntrReply =
4299 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4300 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4301 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4303 sasIoUnitCntrReply->IOCStatus,
4304 sasIoUnitCntrReply->IOCLogInfo);
4308 printk("%s: success\n",__FUNCTION__);
4312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4315 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4316 MpiEventDataRaid_t * pRaidEventData)
4325 volume = pRaidEventData->VolumeID;
4326 reason = pRaidEventData->ReasonCode;
4327 disk = pRaidEventData->PhysDiskNum;
4328 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4329 flags = (status >> 0) & 0xff;
4330 state = (status >> 8) & 0xff;
4332 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4336 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4337 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4338 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4339 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4340 ioc->name, disk, volume);
4342 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4347 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4348 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4352 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4354 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4358 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4359 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4363 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4364 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4366 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4368 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4370 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4373 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4375 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4376 ? ", quiesced" : "",
4377 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4378 ? ", resync in progress" : "" );
4381 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4382 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4386 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4387 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4391 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4392 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4396 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4397 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4401 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4402 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4404 state == MPI_PHYSDISK0_STATUS_ONLINE
4406 : state == MPI_PHYSDISK0_STATUS_MISSING
4408 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4410 : state == MPI_PHYSDISK0_STATUS_FAILED
4412 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4414 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4415 ? "offline requested"
4416 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4417 ? "failed requested"
4418 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4421 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4422 ? ", out of sync" : "",
4423 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4424 ? ", quiesced" : "" );
4427 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4428 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4432 case MPI_EVENT_RAID_RC_SMART_DATA:
4433 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4434 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4437 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4438 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4444 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4446 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4447 * @ioc: Pointer to MPT_ADAPTER structure
4449 * Returns: 0 for success
4450 * -ENOMEM if no memory available
4451 * -EPERM if not allowed due to ISR context
4452 * -EAGAIN if no msg frames currently available
4453 * -EFAULT for non-successful reply or no reply (timeout)
4456 GetIoUnitPage2(MPT_ADAPTER *ioc)
4458 ConfigPageHeader_t hdr;
4460 IOUnitPage2_t *ppage_alloc;
4461 dma_addr_t page_dma;
4465 /* Get the page header */
4466 hdr.PageVersion = 0;
4469 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4470 cfg.cfghdr.hdr = &hdr;
4472 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4477 if ((rc = mpt_config(ioc, &cfg)) != 0)
4480 if (hdr.PageLength == 0)
4483 /* Read the config page */
4484 data_sz = hdr.PageLength * 4;
4486 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4488 memset((u8 *)ppage_alloc, 0, data_sz);
4489 cfg.physAddr = page_dma;
4490 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4492 /* If Good, save data */
4493 if ((rc = mpt_config(ioc, &cfg)) == 0)
4494 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4496 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4502 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4504 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4505 * @ioc: Pointer to a Adapter Strucutre
4506 * @portnum: IOC port number
4508 * Return: -EFAULT if read of config page header fails
4510 * If read of SCSI Port Page 0 fails,
4511 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4512 * Adapter settings: async, narrow
4514 * If read of SCSI Port Page 2 fails,
4515 * Adapter settings valid
4516 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4521 * CHECK - what type of locking mechanisms should be used????
4524 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4529 ConfigPageHeader_t header;
4535 if (!ioc->spi_data.nvram) {
4538 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4539 mem = kmalloc(sz, GFP_ATOMIC);
4543 ioc->spi_data.nvram = (int *) mem;
4545 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4546 ioc->name, ioc->spi_data.nvram, sz));
4549 /* Invalidate NVRAM information
4551 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4552 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4555 /* Read SPP0 header, allocate memory, then read page.
4557 header.PageVersion = 0;
4558 header.PageLength = 0;
4559 header.PageNumber = 0;
4560 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4561 cfg.cfghdr.hdr = &header;
4563 cfg.pageAddr = portnum;
4564 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4566 cfg.timeout = 0; /* use default */
4567 if (mpt_config(ioc, &cfg) != 0)
4570 if (header.PageLength > 0) {
4571 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4573 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4574 cfg.physAddr = buf_dma;
4575 if (mpt_config(ioc, &cfg) != 0) {
4576 ioc->spi_data.maxBusWidth = MPT_NARROW;
4577 ioc->spi_data.maxSyncOffset = 0;
4578 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4579 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4581 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4582 ioc->name, ioc->spi_data.minSyncFactor));
4584 /* Save the Port Page 0 data
4586 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4587 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4588 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4590 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4591 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4592 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4593 ioc->name, pPP0->Capabilities));
4595 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4596 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4598 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4599 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4600 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4601 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4602 ioc->name, ioc->spi_data.minSyncFactor));
4604 ioc->spi_data.maxSyncOffset = 0;
4605 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4608 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4610 /* Update the minSyncFactor based on bus type.
4612 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4613 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4615 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4616 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4617 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4618 ioc->name, ioc->spi_data.minSyncFactor));
4623 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4628 /* SCSI Port Page 2 - Read the header then the page.
4630 header.PageVersion = 0;
4631 header.PageLength = 0;
4632 header.PageNumber = 2;
4633 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4634 cfg.cfghdr.hdr = &header;
4636 cfg.pageAddr = portnum;
4637 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4639 if (mpt_config(ioc, &cfg) != 0)
4642 if (header.PageLength > 0) {
4643 /* Allocate memory and read SCSI Port Page 2
4645 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4647 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4648 cfg.physAddr = buf_dma;
4649 if (mpt_config(ioc, &cfg) != 0) {
4650 /* Nvram data is left with INVALID mark
4654 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4655 MpiDeviceInfo_t *pdevice = NULL;
4658 * Save "Set to Avoid SCSI Bus Resets" flag
4660 ioc->spi_data.bus_reset =
4661 (le32_to_cpu(pPP2->PortFlags) &
4662 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4665 /* Save the Port Page 2 data
4666 * (reformat into a 32bit quantity)
4668 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4669 ioc->spi_data.PortFlags = data;
4670 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4671 pdevice = &pPP2->DeviceSettings[ii];
4672 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4673 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4674 ioc->spi_data.nvram[ii] = data;
4678 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4682 /* Update Adapter limits with those from NVRAM
4683 * Comment: Don't need to do this. Target performance
4684 * parameters will never exceed the adapters limits.
4690 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4692 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
4693 * @ioc: Pointer to a Adapter Strucutre
4694 * @portnum: IOC port number
4696 * Return: -EFAULT if read of config page header fails
4700 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4703 ConfigPageHeader_t header;
4705 /* Read the SCSI Device Page 1 header
4707 header.PageVersion = 0;
4708 header.PageLength = 0;
4709 header.PageNumber = 1;
4710 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4711 cfg.cfghdr.hdr = &header;
4713 cfg.pageAddr = portnum;
4714 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4717 if (mpt_config(ioc, &cfg) != 0)
4720 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4721 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4723 header.PageVersion = 0;
4724 header.PageLength = 0;
4725 header.PageNumber = 0;
4726 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4727 if (mpt_config(ioc, &cfg) != 0)
4730 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4731 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4733 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4734 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4736 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4737 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4742 * mpt_inactive_raid_list_free
4744 * This clears this link list.
4746 * @ioc - pointer to per adapter structure
4750 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
4752 struct inactive_raid_component_info *component_info, *pNext;
4754 if (list_empty(&ioc->raid_data.inactive_list))
4757 down(&ioc->raid_data.inactive_list_mutex);
4758 list_for_each_entry_safe(component_info, pNext,
4759 &ioc->raid_data.inactive_list, list) {
4760 list_del(&component_info->list);
4761 kfree(component_info);
4763 up(&ioc->raid_data.inactive_list_mutex);
4767 * mpt_inactive_raid_volumes
4769 * This sets up link list of phy_disk_nums for devices belonging in an inactive volume
4771 * @ioc - pointer to per adapter structure
4772 * @channel - volume channel
4773 * @id - volume target id
4778 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
4781 ConfigPageHeader_t hdr;
4782 dma_addr_t dma_handle;
4783 pRaidVolumePage0_t buffer = NULL;
4785 RaidPhysDiskPage0_t phys_disk;
4786 struct inactive_raid_component_info *component_info;
4787 int handle_inactive_volumes;
4789 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4790 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4791 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4792 cfg.pageAddr = (channel << 8) + id;
4793 cfg.cfghdr.hdr = &hdr;
4794 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4796 if (mpt_config(ioc, &cfg) != 0)
4799 if (!hdr.PageLength)
4802 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4808 cfg.physAddr = dma_handle;
4809 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4811 if (mpt_config(ioc, &cfg) != 0)
4814 if (!buffer->NumPhysDisks)
4817 handle_inactive_volumes =
4818 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
4819 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
4820 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
4821 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
4823 if (!handle_inactive_volumes)
4826 down(&ioc->raid_data.inactive_list_mutex);
4827 for (i = 0; i < buffer->NumPhysDisks; i++) {
4828 if(mpt_raid_phys_disk_pg0(ioc,
4829 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4832 if ((component_info = kmalloc(sizeof (*component_info),
4833 GFP_KERNEL)) == NULL)
4836 component_info->volumeID = id;
4837 component_info->volumeBus = channel;
4838 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
4839 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
4840 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
4841 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
4843 list_add_tail(&component_info->list,
4844 &ioc->raid_data.inactive_list);
4846 up(&ioc->raid_data.inactive_list_mutex);
4850 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4855 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
4856 * @ioc: Pointer to a Adapter Structure
4857 * @phys_disk_num: io unit unique phys disk num generated by the ioc
4858 * @phys_disk: requested payload data returned
4862 * -EFAULT if read of config page header fails or data pointer not NULL
4863 * -ENOMEM if pci_alloc failed
4866 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
4869 ConfigPageHeader_t hdr;
4870 dma_addr_t dma_handle;
4871 pRaidPhysDiskPage0_t buffer = NULL;
4874 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4875 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4877 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
4878 cfg.cfghdr.hdr = &hdr;
4880 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4882 if (mpt_config(ioc, &cfg) != 0) {
4887 if (!hdr.PageLength) {
4892 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4900 cfg.physAddr = dma_handle;
4901 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4902 cfg.pageAddr = phys_disk_num;
4904 if (mpt_config(ioc, &cfg) != 0) {
4910 memcpy(phys_disk, buffer, sizeof(*buffer));
4911 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
4916 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4923 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4924 * @ioc: Pointer to a Adapter Strucutre
4925 * @portnum: IOC port number
4929 * -EFAULT if read of config page header fails or data pointer not NULL
4930 * -ENOMEM if pci_alloc failed
4933 mpt_findImVolumes(MPT_ADAPTER *ioc)
4937 dma_addr_t ioc2_dma;
4939 ConfigPageHeader_t header;
4944 if (!ioc->ir_firmware)
4947 /* Free the old page
4949 kfree(ioc->raid_data.pIocPg2);
4950 ioc->raid_data.pIocPg2 = NULL;
4951 mpt_inactive_raid_list_free(ioc);
4953 /* Read IOCP2 header then the page.
4955 header.PageVersion = 0;
4956 header.PageLength = 0;
4957 header.PageNumber = 2;
4958 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4959 cfg.cfghdr.hdr = &header;
4962 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4965 if (mpt_config(ioc, &cfg) != 0)
4968 if (header.PageLength == 0)
4971 iocpage2sz = header.PageLength * 4;
4972 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4976 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4977 cfg.physAddr = ioc2_dma;
4978 if (mpt_config(ioc, &cfg) != 0)
4981 mem = kmalloc(iocpage2sz, GFP_KERNEL);
4985 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4986 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4988 mpt_read_ioc_pg_3(ioc);
4990 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
4991 mpt_inactive_raid_volumes(ioc,
4992 pIoc2->RaidVolume[i].VolumeBus,
4993 pIoc2->RaidVolume[i].VolumeID);
4996 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5002 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5007 ConfigPageHeader_t header;
5008 dma_addr_t ioc3_dma;
5011 /* Free the old page
5013 kfree(ioc->raid_data.pIocPg3);
5014 ioc->raid_data.pIocPg3 = NULL;
5016 /* There is at least one physical disk.
5017 * Read and save IOC Page 3
5019 header.PageVersion = 0;
5020 header.PageLength = 0;
5021 header.PageNumber = 3;
5022 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5023 cfg.cfghdr.hdr = &header;
5026 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5029 if (mpt_config(ioc, &cfg) != 0)
5032 if (header.PageLength == 0)
5035 /* Read Header good, alloc memory
5037 iocpage3sz = header.PageLength * 4;
5038 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5042 /* Read the Page and save the data
5043 * into malloc'd memory.
5045 cfg.physAddr = ioc3_dma;
5046 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5047 if (mpt_config(ioc, &cfg) == 0) {
5048 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5050 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5051 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5055 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5061 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5065 ConfigPageHeader_t header;
5066 dma_addr_t ioc4_dma;
5069 /* Read and save IOC Page 4
5071 header.PageVersion = 0;
5072 header.PageLength = 0;
5073 header.PageNumber = 4;
5074 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5075 cfg.cfghdr.hdr = &header;
5078 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5081 if (mpt_config(ioc, &cfg) != 0)
5084 if (header.PageLength == 0)
5087 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5088 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5089 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5092 ioc->alloc_total += iocpage4sz;
5094 ioc4_dma = ioc->spi_data.IocPg4_dma;
5095 iocpage4sz = ioc->spi_data.IocPg4Sz;
5098 /* Read the Page into dma memory.
5100 cfg.physAddr = ioc4_dma;
5101 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5102 if (mpt_config(ioc, &cfg) == 0) {
5103 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5104 ioc->spi_data.IocPg4_dma = ioc4_dma;
5105 ioc->spi_data.IocPg4Sz = iocpage4sz;
5107 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5108 ioc->spi_data.pIocPg4 = NULL;
5109 ioc->alloc_total -= iocpage4sz;
5114 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5118 ConfigPageHeader_t header;
5119 dma_addr_t ioc1_dma;
5123 /* Check the Coalescing Timeout in IOC Page 1
5125 header.PageVersion = 0;
5126 header.PageLength = 0;
5127 header.PageNumber = 1;
5128 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5129 cfg.cfghdr.hdr = &header;
5132 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5135 if (mpt_config(ioc, &cfg) != 0)
5138 if (header.PageLength == 0)
5141 /* Read Header good, alloc memory
5143 iocpage1sz = header.PageLength * 4;
5144 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5148 /* Read the Page and check coalescing timeout
5150 cfg.physAddr = ioc1_dma;
5151 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5152 if (mpt_config(ioc, &cfg) == 0) {
5154 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5155 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5156 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5158 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
5161 if (tmp > MPT_COALESCING_TIMEOUT) {
5162 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5164 /* Write NVRAM and current
5167 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5168 if (mpt_config(ioc, &cfg) == 0) {
5169 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5170 ioc->name, MPT_COALESCING_TIMEOUT));
5172 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5173 if (mpt_config(ioc, &cfg) == 0) {
5174 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5175 ioc->name, MPT_COALESCING_TIMEOUT));
5177 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5182 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5188 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5192 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5199 * SendEventNotification - Send EventNotification (on or off) request to adapter
5200 * @ioc: Pointer to MPT_ADAPTER structure
5201 * @EvSwitch: Event switch flags
5204 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5206 EventNotification_t *evnp;
5208 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5210 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5214 memset(evnp, 0, sizeof(*evnp));
5216 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5218 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5219 evnp->ChainOffset = 0;
5221 evnp->Switch = EvSwitch;
5223 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5228 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5230 * SendEventAck - Send EventAck request to MPT adapter.
5231 * @ioc: Pointer to MPT_ADAPTER structure
5232 * @evnp: Pointer to original EventNotification request
5235 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5239 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5240 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5241 ioc->name,__FUNCTION__));
5245 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5247 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5248 pAck->ChainOffset = 0;
5249 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5251 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5252 pAck->Event = evnp->Event;
5253 pAck->EventContext = evnp->EventContext;
5255 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5262 * mpt_config - Generic function to issue config message
5263 * @ioc: Pointer to an adapter structure
5264 * @pCfg: Pointer to a configuration structure. Struct contains
5265 * action, page address, direction, physical address
5266 * and pointer to a configuration page header
5267 * Page header is updated.
5269 * Returns 0 for success
5270 * -EPERM if not allowed due to ISR context
5271 * -EAGAIN if no msg frames currently available
5272 * -EFAULT for non-successful reply or no reply (timeout)
5275 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5278 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5280 unsigned long flags;
5285 /* Prevent calling wait_event() (below), if caller happens
5286 * to be in ISR context, because that is fatal!
5288 in_isr = in_interrupt();
5290 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5295 /* Get and Populate a free Frame
5297 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5298 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5302 pReq = (Config_t *)mf;
5303 pReq->Action = pCfg->action;
5305 pReq->ChainOffset = 0;
5306 pReq->Function = MPI_FUNCTION_CONFIG;
5308 /* Assume page type is not extended and clear "reserved" fields. */
5309 pReq->ExtPageLength = 0;
5310 pReq->ExtPageType = 0;
5313 for (ii=0; ii < 8; ii++)
5314 pReq->Reserved2[ii] = 0;
5316 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5317 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5318 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5319 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5321 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5322 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5323 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5324 pReq->ExtPageType = pExtHdr->ExtPageType;
5325 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5327 /* Page Length must be treated as a reserved field for the extended header. */
5328 pReq->Header.PageLength = 0;
5331 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5333 /* Add a SGE to the config request.
5336 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5338 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5340 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5341 flagsLength |= pExtHdr->ExtPageLength * 4;
5343 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5344 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5347 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5349 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5350 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5353 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5355 /* Append pCfg pointer to end of mf
5357 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5359 /* Initalize the timer
5361 init_timer(&pCfg->timer);
5362 pCfg->timer.data = (unsigned long) ioc;
5363 pCfg->timer.function = mpt_timer_expired;
5364 pCfg->wait_done = 0;
5366 /* Set the timer; ensure 10 second minimum */
5367 if (pCfg->timeout < 10)
5368 pCfg->timer.expires = jiffies + HZ*10;
5370 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5372 /* Add to end of Q, set timer and then issue this command */
5373 spin_lock_irqsave(&ioc->FreeQlock, flags);
5374 list_add_tail(&pCfg->linkage, &ioc->configQ);
5375 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5377 add_timer(&pCfg->timer);
5378 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5379 wait_event(mpt_waitq, pCfg->wait_done);
5381 /* mf has been freed - do not access */
5388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5390 * mpt_timer_expired - Callback for timer process.
5391 * Used only internal config functionality.
5392 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5395 mpt_timer_expired(unsigned long data)
5397 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5399 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5401 /* Perform a FW reload */
5402 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5403 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5405 /* No more processing.
5406 * Hard reset clean-up will wake up
5407 * process and free all resources.
5409 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5414 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5416 * mpt_ioc_reset - Base cleanup for hard reset
5417 * @ioc: Pointer to the adapter structure
5418 * @reset_phase: Indicates pre- or post-reset functionality
5420 * Remark: Frees resources with internally generated commands.
5423 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5426 unsigned long flags;
5428 dprintk((KERN_WARNING MYNAM
5429 ": IOC %s_reset routed to MPT base driver!\n",
5430 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5431 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5433 if (reset_phase == MPT_IOC_SETUP_RESET) {
5435 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5436 /* If the internal config Q is not empty -
5437 * delete timer. MF resources will be freed when
5438 * the FIFO's are primed.
5440 spin_lock_irqsave(&ioc->FreeQlock, flags);
5441 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5442 del_timer(&pCfg->timer);
5443 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5448 /* Search the configQ for internal commands.
5449 * Flush the Q, and wake up all suspended threads.
5451 spin_lock_irqsave(&ioc->FreeQlock, flags);
5452 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5453 list_del(&pCfg->linkage);
5455 pCfg->status = MPT_CONFIG_ERROR;
5456 pCfg->wait_done = 1;
5457 wake_up(&mpt_waitq);
5459 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5462 return 1; /* currently means nothing really */
5466 #ifdef CONFIG_PROC_FS /* { */
5467 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5469 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5471 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5473 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5475 * Returns 0 for success, non-zero for failure.
5478 procmpt_create(void)
5480 struct proc_dir_entry *ent;
5482 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5483 if (mpt_proc_root_dir == NULL)
5486 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5488 ent->read_proc = procmpt_summary_read;
5490 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5492 ent->read_proc = procmpt_version_read;
5497 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5499 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5501 * Returns 0 for success, non-zero for failure.
5504 procmpt_destroy(void)
5506 remove_proc_entry("version", mpt_proc_root_dir);
5507 remove_proc_entry("summary", mpt_proc_root_dir);
5508 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5513 * procmpt_summary_read - Handle read request of a summary file
5514 * @buf: Pointer to area to write information
5515 * @start: Pointer to start pointer
5516 * @offset: Offset to start writing
5517 * @request: Amount of read data requested
5518 * @eof: Pointer to EOF integer
5521 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5522 * Returns number of characters written to process performing the read.
5525 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5535 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5539 list_for_each_entry(ioc, &ioc_list, list) {
5542 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5545 if ((out-buf) >= request)
5552 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5555 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5557 * procmpt_version_read - Handle read request from /proc/mpt/version.
5558 * @buf: Pointer to area to write information
5559 * @start: Pointer to start pointer
5560 * @offset: Offset to start writing
5561 * @request: Amount of read data requested
5562 * @eof: Pointer to EOF integer
5565 * Returns number of characters written to process performing the read.
5568 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5571 int scsi, fc, sas, lan, ctl, targ, dmp;
5575 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5576 len += sprintf(buf+len, " Fusion MPT base driver\n");
5578 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5579 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5581 if (MptCallbacks[ii]) {
5582 switch (MptDriverClass[ii]) {
5584 if (!scsi++) drvname = "SPI host";
5587 if (!fc++) drvname = "FC host";
5590 if (!sas++) drvname = "SAS host";
5593 if (!lan++) drvname = "LAN";
5596 if (!targ++) drvname = "SCSI target";
5599 if (!ctl++) drvname = "ioctl";
5604 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5608 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5611 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5613 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5614 * @buf: Pointer to area to write information
5615 * @start: Pointer to start pointer
5616 * @offset: Offset to start writing
5617 * @request: Amount of read data requested
5618 * @eof: Pointer to EOF integer
5621 * Returns number of characters written to process performing the read.
5624 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5626 MPT_ADAPTER *ioc = data;
5632 mpt_get_fw_exp_ver(expVer, ioc);
5634 len = sprintf(buf, "%s:", ioc->name);
5635 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5636 len += sprintf(buf+len, " (f/w download boot flag set)");
5637 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5638 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5640 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5641 ioc->facts.ProductID,
5643 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5644 if (ioc->facts.FWImageSize)
5645 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5646 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5647 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5648 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5650 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5651 ioc->facts.CurrentHostMfaHighAddr);
5652 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5653 ioc->facts.CurrentSenseBufferHighAddr);
5655 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5656 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5658 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5659 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5661 * Rounding UP to nearest 4-kB boundary here...
5663 sz = (ioc->req_sz * ioc->req_depth) + 128;
5664 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5665 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5666 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5667 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5668 4*ioc->facts.RequestFrameSize,
5669 ioc->facts.GlobalCredits);
5671 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5672 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5673 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5674 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5675 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5676 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5677 ioc->facts.CurReplyFrameSize,
5678 ioc->facts.ReplyQueueDepth);
5680 len += sprintf(buf+len, " MaxDevices = %d\n",
5681 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5682 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5685 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5686 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5688 ioc->facts.NumberOfPorts);
5689 if (ioc->bus_type == FC) {
5690 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5691 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5692 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5693 a[5], a[4], a[3], a[2], a[1], a[0]);
5695 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5696 ioc->fc_port_page0[p].WWNN.High,
5697 ioc->fc_port_page0[p].WWNN.Low,
5698 ioc->fc_port_page0[p].WWPN.High,
5699 ioc->fc_port_page0[p].WWPN.Low);
5703 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5706 #endif /* CONFIG_PROC_FS } */
5708 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5710 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5713 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5714 sprintf(buf, " (Exp %02d%02d)",
5715 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5716 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5719 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5720 strcat(buf, " [MDBG]");
5724 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5726 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5727 * @ioc: Pointer to MPT_ADAPTER structure
5728 * @buffer: Pointer to buffer where IOC summary info should be written
5729 * @size: Pointer to number of bytes we wrote (set by this routine)
5730 * @len: Offset at which to start writing in buffer
5731 * @showlan: Display LAN stuff?
5733 * This routine writes (english readable) ASCII text, which represents
5734 * a summary of IOC information, to a buffer.
5737 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5742 mpt_get_fw_exp_ver(expVer, ioc);
5745 * Shorter summary of attached ioc's...
5747 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5750 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5751 ioc->facts.FWVersion.Word,
5753 ioc->facts.NumberOfPorts,
5756 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5757 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5758 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5759 a[5], a[4], a[3], a[2], a[1], a[0]);
5762 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5765 y += sprintf(buffer+len+y, " (disabled)");
5767 y += sprintf(buffer+len+y, "\n");
5772 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5776 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5778 * mpt_HardResetHandler - Generic reset handler
5779 * @ioc: Pointer to MPT_ADAPTER structure
5780 * @sleepFlag: Indicates if sleep or schedule must be called.
5782 * Issues SCSI Task Management call based on input arg values.
5783 * If TaskMgmt fails, returns associated SCSI request.
5785 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5786 * or a non-interrupt thread. In the former, must not call schedule().
5788 * Note: A return of -1 is a FATAL error case, as it means a
5789 * FW reload/initialization failed.
5791 * Returns 0 for SUCCESS or -1 if FAILED.
5794 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5797 unsigned long flags;
5799 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5801 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5802 printk("MF count 0x%x !\n", ioc->mfcnt);
5805 /* Reset the adapter. Prevent more than 1 call to
5806 * mpt_do_ioc_recovery at any instant in time.
5808 spin_lock_irqsave(&ioc->diagLock, flags);
5809 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5810 spin_unlock_irqrestore(&ioc->diagLock, flags);
5813 ioc->diagPending = 1;
5815 spin_unlock_irqrestore(&ioc->diagLock, flags);
5817 /* FIXME: If do_ioc_recovery fails, repeat....
5820 /* The SCSI driver needs to adjust timeouts on all current
5821 * commands prior to the diagnostic reset being issued.
5822 * Prevents timeouts occurring during a diagnostic reset...very bad.
5823 * For all other protocol drivers, this is a no-op.
5829 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5830 if (MptResetHandlers[ii]) {
5831 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5833 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5835 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5836 ioc->name, ioc->alt_ioc->name, ii));
5837 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5843 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5844 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5849 ioc->alt_ioc->reload_fw = 0;
5851 spin_lock_irqsave(&ioc->diagLock, flags);
5852 ioc->diagPending = 0;
5854 ioc->alt_ioc->diagPending = 0;
5855 spin_unlock_irqrestore(&ioc->diagLock, flags);
5857 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5864 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5869 case MPI_EVENT_NONE:
5872 case MPI_EVENT_LOG_DATA:
5875 case MPI_EVENT_STATE_CHANGE:
5876 ds = "State Change";
5878 case MPI_EVENT_UNIT_ATTENTION:
5879 ds = "Unit Attention";
5881 case MPI_EVENT_IOC_BUS_RESET:
5882 ds = "IOC Bus Reset";
5884 case MPI_EVENT_EXT_BUS_RESET:
5885 ds = "External Bus Reset";
5887 case MPI_EVENT_RESCAN:
5888 ds = "Bus Rescan Event";
5890 case MPI_EVENT_LINK_STATUS_CHANGE:
5891 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5892 ds = "Link Status(FAILURE) Change";
5894 ds = "Link Status(ACTIVE) Change";
5896 case MPI_EVENT_LOOP_STATE_CHANGE:
5897 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5898 ds = "Loop State(LIP) Change";
5899 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5900 ds = "Loop State(LPE) Change"; /* ??? */
5902 ds = "Loop State(LPB) Change"; /* ??? */
5904 case MPI_EVENT_LOGOUT:
5907 case MPI_EVENT_EVENT_CHANGE:
5913 case MPI_EVENT_INTEGRATED_RAID:
5915 u8 ReasonCode = (u8)(evData0 >> 16);
5916 switch (ReasonCode) {
5917 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5918 ds = "Integrated Raid: Volume Created";
5920 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5921 ds = "Integrated Raid: Volume Deleted";
5923 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5924 ds = "Integrated Raid: Volume Settings Changed";
5926 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5927 ds = "Integrated Raid: Volume Status Changed";
5929 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5930 ds = "Integrated Raid: Volume Physdisk Changed";
5932 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5933 ds = "Integrated Raid: Physdisk Created";
5935 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5936 ds = "Integrated Raid: Physdisk Deleted";
5938 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5939 ds = "Integrated Raid: Physdisk Settings Changed";
5941 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5942 ds = "Integrated Raid: Physdisk Status Changed";
5944 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5945 ds = "Integrated Raid: Domain Validation Needed";
5947 case MPI_EVENT_RAID_RC_SMART_DATA :
5948 ds = "Integrated Raid; Smart Data";
5950 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5951 ds = "Integrated Raid: Replace Action Started";
5954 ds = "Integrated Raid";
5959 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5960 ds = "SCSI Device Status Change";
5962 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5964 u8 id = (u8)(evData0);
5965 u8 channel = (u8)(evData0 >> 8);
5966 u8 ReasonCode = (u8)(evData0 >> 16);
5967 switch (ReasonCode) {
5968 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5969 snprintf(evStr, EVENT_DESCR_STR_SZ,
5970 "SAS Device Status Change: Added: "
5971 "id=%d channel=%d", id, channel);
5973 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5974 snprintf(evStr, EVENT_DESCR_STR_SZ,
5975 "SAS Device Status Change: Deleted: "
5976 "id=%d channel=%d", id, channel);
5978 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5979 snprintf(evStr, EVENT_DESCR_STR_SZ,
5980 "SAS Device Status Change: SMART Data: "
5981 "id=%d channel=%d", id, channel);
5983 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5984 snprintf(evStr, EVENT_DESCR_STR_SZ,
5985 "SAS Device Status Change: No Persistancy: "
5986 "id=%d channel=%d", id, channel);
5988 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
5989 snprintf(evStr, EVENT_DESCR_STR_SZ,
5990 "SAS Device Status Change: Unsupported Device "
5991 "Discovered : id=%d channel=%d", id, channel);
5993 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
5994 snprintf(evStr, EVENT_DESCR_STR_SZ,
5995 "SAS Device Status Change: Internal Device "
5996 "Reset : id=%d channel=%d", id, channel);
5998 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
5999 snprintf(evStr, EVENT_DESCR_STR_SZ,
6000 "SAS Device Status Change: Internal Task "
6001 "Abort : id=%d channel=%d", id, channel);
6003 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6004 snprintf(evStr, EVENT_DESCR_STR_SZ,
6005 "SAS Device Status Change: Internal Abort "
6006 "Task Set : id=%d channel=%d", id, channel);
6008 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6009 snprintf(evStr, EVENT_DESCR_STR_SZ,
6010 "SAS Device Status Change: Internal Clear "
6011 "Task Set : id=%d channel=%d", id, channel);
6013 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6014 snprintf(evStr, EVENT_DESCR_STR_SZ,
6015 "SAS Device Status Change: Internal Query "
6016 "Task : id=%d channel=%d", id, channel);
6019 snprintf(evStr, EVENT_DESCR_STR_SZ,
6020 "SAS Device Status Change: Unknown: "
6021 "id=%d channel=%d", id, channel);
6026 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6027 ds = "Bus Timer Expired";
6029 case MPI_EVENT_QUEUE_FULL:
6031 u16 curr_depth = (u16)(evData0 >> 16);
6032 u8 channel = (u8)(evData0 >> 8);
6033 u8 id = (u8)(evData0);
6035 snprintf(evStr, EVENT_DESCR_STR_SZ,
6036 "Queue Full: channel=%d id=%d depth=%d",
6037 channel, id, curr_depth);
6040 case MPI_EVENT_SAS_SES:
6041 ds = "SAS SES Event";
6043 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6044 ds = "Persistent Table Full";
6046 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6048 u8 LinkRates = (u8)(evData0 >> 8);
6049 u8 PhyNumber = (u8)(evData0);
6050 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6051 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6052 switch (LinkRates) {
6053 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6054 snprintf(evStr, EVENT_DESCR_STR_SZ,
6055 "SAS PHY Link Status: Phy=%d:"
6056 " Rate Unknown",PhyNumber);
6058 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6059 snprintf(evStr, EVENT_DESCR_STR_SZ,
6060 "SAS PHY Link Status: Phy=%d:"
6061 " Phy Disabled",PhyNumber);
6063 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6064 snprintf(evStr, EVENT_DESCR_STR_SZ,
6065 "SAS PHY Link Status: Phy=%d:"
6066 " Failed Speed Nego",PhyNumber);
6068 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6069 snprintf(evStr, EVENT_DESCR_STR_SZ,
6070 "SAS PHY Link Status: Phy=%d:"
6071 " Sata OOB Completed",PhyNumber);
6073 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6074 snprintf(evStr, EVENT_DESCR_STR_SZ,
6075 "SAS PHY Link Status: Phy=%d:"
6076 " Rate 1.5 Gbps",PhyNumber);
6078 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6079 snprintf(evStr, EVENT_DESCR_STR_SZ,
6080 "SAS PHY Link Status: Phy=%d:"
6081 " Rate 3.0 Gpbs",PhyNumber);
6084 snprintf(evStr, EVENT_DESCR_STR_SZ,
6085 "SAS PHY Link Status: Phy=%d", PhyNumber);
6090 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6091 ds = "SAS Discovery Error";
6093 case MPI_EVENT_IR_RESYNC_UPDATE:
6095 u8 resync_complete = (u8)(evData0 >> 16);
6096 snprintf(evStr, EVENT_DESCR_STR_SZ,
6097 "IR Resync Update: Complete = %d:",resync_complete);
6102 u8 ReasonCode = (u8)(evData0 >> 16);
6103 switch (ReasonCode) {
6104 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6105 ds = "IR2: LD State Changed";
6107 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6108 ds = "IR2: PD State Changed";
6110 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6111 ds = "IR2: Bad Block Table Full";
6113 case MPI_EVENT_IR2_RC_PD_INSERTED:
6114 ds = "IR2: PD Inserted";
6116 case MPI_EVENT_IR2_RC_PD_REMOVED:
6117 ds = "IR2: PD Removed";
6119 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6120 ds = "IR2: Foreign CFG Detected";
6122 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6123 ds = "IR2: Rebuild Medium Error";
6131 case MPI_EVENT_SAS_DISCOVERY:
6134 ds = "SAS Discovery: Start";
6136 ds = "SAS Discovery: Stop";
6139 case MPI_EVENT_LOG_ENTRY_ADDED:
6140 ds = "SAS Log Entry Added";
6143 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6145 u8 phy_num = (u8)(evData0);
6146 u8 port_num = (u8)(evData0 >> 8);
6147 u8 port_width = (u8)(evData0 >> 16);
6148 u8 primative = (u8)(evData0 >> 24);
6149 snprintf(evStr, EVENT_DESCR_STR_SZ,
6150 "SAS Broadcase Primative: phy=%d port=%d "
6151 "width=%d primative=0x%02x",
6152 phy_num, port_num, port_width, primative);
6156 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6158 u8 reason = (u8)(evData0);
6159 u8 port_num = (u8)(evData0 >> 8);
6160 u16 handle = le16_to_cpu(evData0 >> 16);
6162 snprintf(evStr, EVENT_DESCR_STR_SZ,
6163 "SAS Initiator Device Status Change: reason=0x%02x "
6164 "port=%d handle=0x%04x",
6165 reason, port_num, handle);
6169 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6171 u8 max_init = (u8)(evData0);
6172 u8 current_init = (u8)(evData0 >> 8);
6174 snprintf(evStr, EVENT_DESCR_STR_SZ,
6175 "SAS Initiator Device Table Overflow: max initiators=%02d "
6176 "current initators=%02d",
6177 max_init, current_init);
6180 case MPI_EVENT_SAS_SMP_ERROR:
6182 u8 status = (u8)(evData0);
6183 u8 port_num = (u8)(evData0 >> 8);
6184 u8 result = (u8)(evData0 >> 16);
6186 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6187 snprintf(evStr, EVENT_DESCR_STR_SZ,
6188 "SAS SMP Error: port=%d result=0x%02x",
6190 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6191 snprintf(evStr, EVENT_DESCR_STR_SZ,
6192 "SAS SMP Error: port=%d : CRC Error",
6194 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6195 snprintf(evStr, EVENT_DESCR_STR_SZ,
6196 "SAS SMP Error: port=%d : Timeout",
6198 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6199 snprintf(evStr, EVENT_DESCR_STR_SZ,
6200 "SAS SMP Error: port=%d : No Destination",
6202 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6203 snprintf(evStr, EVENT_DESCR_STR_SZ,
6204 "SAS SMP Error: port=%d : Bad Destination",
6207 snprintf(evStr, EVENT_DESCR_STR_SZ,
6208 "SAS SMP Error: port=%d : status=0x%02x",
6214 * MPT base "custom" events may be added here...
6221 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6226 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6227 * @ioc: Pointer to MPT_ADAPTER structure
6228 * @pEventReply: Pointer to EventNotification reply frame
6229 * @evHandlers: Pointer to integer, number of event handlers
6231 * Routes a received EventNotificationReply to all currently registered
6233 * Returns sum of event handlers return values.
6236 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6244 char evStr[EVENT_DESCR_STR_SZ];
6248 * Do platform normalization of values
6250 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6251 // evCtx = le32_to_cpu(pEventReply->EventContext);
6252 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6254 evData0 = le32_to_cpu(pEventReply->Data[0]);
6257 EventDescriptionStr(event, evData0, evStr);
6258 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
6263 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6264 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6265 for (ii = 0; ii < evDataLen; ii++)
6266 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6271 * Do general / base driver event processing
6274 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6276 u8 evState = evData0 & 0xFF;
6278 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6280 /* Update EventState field in cached IocFacts */
6281 if (ioc->facts.Function) {
6282 ioc->facts.EventState = evState;
6286 case MPI_EVENT_INTEGRATED_RAID:
6287 mptbase_raid_process_event_data(ioc,
6288 (MpiEventDataRaid_t *)pEventReply->Data);
6295 * Should this event be logged? Events are written sequentially.
6296 * When buffer is full, start again at the top.
6298 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6301 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6303 ioc->events[idx].event = event;
6304 ioc->events[idx].eventContext = ioc->eventContext;
6306 for (ii = 0; ii < 2; ii++) {
6308 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6310 ioc->events[idx].data[ii] = 0;
6313 ioc->eventContext++;
6318 * Call each currently registered protocol event handler.
6320 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6321 if (MptEvHandlers[ii]) {
6322 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6324 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6328 /* FIXME? Examine results here? */
6331 * If needed, send (a single) EventAck.
6333 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6334 devtverboseprintk((MYIOC_s_WARN_FMT
6335 "EventAck required\n",ioc->name));
6336 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6337 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6342 *evHandlers = handlers;
6346 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6348 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6349 * @ioc: Pointer to MPT_ADAPTER structure
6350 * @log_info: U32 LogInfo reply word from the IOC
6352 * Refer to lsi/mpi_log_fc.h.
6355 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6357 static char *subcl_str[8] = {
6358 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6359 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6361 u8 subcl = (log_info >> 24) & 0x7;
6363 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6364 ioc->name, log_info, subcl_str[subcl]);
6367 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6369 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6370 * @ioc: Pointer to MPT_ADAPTER structure
6371 * @mr: Pointer to MPT reply frame
6372 * @log_info: U32 LogInfo word from the IOC
6374 * Refer to lsi/sp_log.h.
6377 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6379 u32 info = log_info & 0x00FF0000;
6380 char *desc = "unknown";
6384 desc = "bug! MID not found";
6385 if (ioc->reload_fw == 0)
6390 desc = "Parity Error";
6394 desc = "ASYNC Outbound Overrun";
6398 desc = "SYNC Offset Error";
6406 desc = "Msg In Overflow";
6414 desc = "Outbound DMA Overrun";
6418 desc = "Task Management";
6422 desc = "Device Problem";
6426 desc = "Invalid Phase Change";
6430 desc = "Untagged Table Size";
6435 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6438 /* strings for sas loginfo */
6439 static char *originator_str[] = {
6444 static char *iop_code_str[] = {
6446 "Invalid SAS Address", /* 01h */
6448 "Invalid Page", /* 03h */
6449 "Diag Message Error", /* 04h */
6450 "Task Terminated", /* 05h */
6451 "Enclosure Management", /* 06h */
6452 "Target Mode" /* 07h */
6454 static char *pl_code_str[] = {
6456 "Open Failure", /* 01h */
6457 "Invalid Scatter Gather List", /* 02h */
6458 "Wrong Relative Offset or Frame Length", /* 03h */
6459 "Frame Transfer Error", /* 04h */
6460 "Transmit Frame Connected Low", /* 05h */
6461 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6462 "SATA Read Log Receive Data Error", /* 07h */
6463 "SATA NCQ Fail All Commands After Error", /* 08h */
6464 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6465 "Receive Frame Invalid Message", /* 0Ah */
6466 "Receive Context Message Valid Error", /* 0Bh */
6467 "Receive Frame Current Frame Error", /* 0Ch */
6468 "SATA Link Down", /* 0Dh */
6469 "Discovery SATA Init W IOS", /* 0Eh */
6470 "Config Invalid Page", /* 0Fh */
6471 "Discovery SATA Init Timeout", /* 10h */
6474 "IO Not Yet Executed", /* 13h */
6475 "IO Executed", /* 14h */
6476 "Persistent Reservation Out Not Affiliation "
6478 "Open Transmit DMA Abort", /* 16h */
6479 "IO Device Missing Delay Retry", /* 17h */
6480 "IO Cancelled Due to Recieve Error", /* 18h */
6488 "Enclosure Management" /* 20h */
6490 static char *ir_code_str[] = {
6491 "Raid Action Error", /* 00h */
6501 static char *raid_sub_code_str[] = {
6503 "Volume Creation Failed: Data Passed too "
6505 "Volume Creation Failed: Duplicate Volumes "
6506 "Attempted", /* 02h */
6507 "Volume Creation Failed: Max Number "
6508 "Supported Volumes Exceeded", /* 03h */
6509 "Volume Creation Failed: DMA Error", /* 04h */
6510 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6511 "Volume Creation Failed: Error Reading "
6512 "MFG Page 4", /* 06h */
6513 "Volume Creation Failed: Creating Internal "
6514 "Structures", /* 07h */
6523 "Activation failed: Already Active Volume", /* 10h */
6524 "Activation failed: Unsupported Volume Type", /* 11h */
6525 "Activation failed: Too Many Active Volumes", /* 12h */
6526 "Activation failed: Volume ID in Use", /* 13h */
6527 "Activation failed: Reported Failure", /* 14h */
6528 "Activation failed: Importing a Volume", /* 15h */
6539 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6540 "Phys Disk failed: Data Passed too Large", /* 21h */
6541 "Phys Disk failed: DMA Error", /* 22h */
6542 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6543 "Phys Disk failed: Creating Phys Disk Config "
6556 "Compatibility Error: IR Disabled", /* 30h */
6557 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6558 "Compatibility Error: Device not Direct Access "
6559 "Device ", /* 32h */
6560 "Compatibility Error: Removable Device Found", /* 33h */
6561 "Compatibility Error: Device SCSI Version not "
6562 "2 or Higher", /* 34h */
6563 "Compatibility Error: SATA Device, 48 BIT LBA "
6564 "not Supported", /* 35h */
6565 "Compatibility Error: Device doesn't have "
6566 "512 Byte Block Sizes", /* 36h */
6567 "Compatibility Error: Volume Type Check Failed", /* 37h */
6568 "Compatibility Error: Volume Type is "
6569 "Unsupported by FW", /* 38h */
6570 "Compatibility Error: Disk Drive too Small for "
6571 "use in Volume", /* 39h */
6572 "Compatibility Error: Phys Disk for Create "
6573 "Volume not Found", /* 3Ah */
6574 "Compatibility Error: Too Many or too Few "
6575 "Disks for Volume Type", /* 3Bh */
6576 "Compatibility Error: Disk stripe Sizes "
6577 "Must be 64KB", /* 3Ch */
6578 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6581 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6583 * mpt_sas_log_info - Log information returned from SAS IOC.
6584 * @ioc: Pointer to MPT_ADAPTER structure
6585 * @log_info: U32 LogInfo reply word from the IOC
6587 * Refer to lsi/mpi_log_sas.h.
6590 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6592 union loginfo_type {
6601 union loginfo_type sas_loginfo;
6602 char *originator_desc = NULL;
6603 char *code_desc = NULL;
6604 char *sub_code_desc = NULL;
6606 sas_loginfo.loginfo = log_info;
6607 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6608 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6611 originator_desc = originator_str[sas_loginfo.dw.originator];
6613 switch (sas_loginfo.dw.originator) {
6616 if (sas_loginfo.dw.code <
6617 sizeof(iop_code_str)/sizeof(char*))
6618 code_desc = iop_code_str[sas_loginfo.dw.code];
6621 if (sas_loginfo.dw.code <
6622 sizeof(pl_code_str)/sizeof(char*))
6623 code_desc = pl_code_str[sas_loginfo.dw.code];
6626 if (sas_loginfo.dw.code >=
6627 sizeof(ir_code_str)/sizeof(char*))
6629 code_desc = ir_code_str[sas_loginfo.dw.code];
6630 if (sas_loginfo.dw.subcode >=
6631 sizeof(raid_sub_code_str)/sizeof(char*))
6633 if (sas_loginfo.dw.code == 0)
6635 raid_sub_code_str[sas_loginfo.dw.subcode];
6641 if (sub_code_desc != NULL)
6642 printk(MYIOC_s_INFO_FMT
6643 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6645 ioc->name, log_info, originator_desc, code_desc,
6647 else if (code_desc != NULL)
6648 printk(MYIOC_s_INFO_FMT
6649 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6650 " SubCode(0x%04x)\n",
6651 ioc->name, log_info, originator_desc, code_desc,
6652 sas_loginfo.dw.subcode);
6654 printk(MYIOC_s_INFO_FMT
6655 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6656 " SubCode(0x%04x)\n",
6657 ioc->name, log_info, originator_desc,
6658 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6661 #ifdef MPT_DEBUG_REPLY
6662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6664 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
6665 * @ioc: Pointer to MPT_ADAPTER structure
6666 * ioc_status: U32 IOCStatus word from IOC
6667 * @mf: Pointer to MPT request frame
6669 * Refer to lsi/mpi.h.
6672 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6674 Config_t *pReq = (Config_t *)mf;
6675 char extend_desc[EVENT_DESCR_STR_SZ];
6680 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
6681 page_type = pReq->ExtPageType;
6683 page_type = pReq->Header.PageType;
6686 * ignore invalid page messages for GET_NEXT_HANDLE
6688 form = le32_to_cpu(pReq->PageAddress);
6689 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
6690 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
6691 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
6692 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
6693 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
6694 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
6697 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
6698 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
6699 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
6703 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
6704 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
6705 page_type, pReq->Header.PageNumber, pReq->Action, form);
6707 switch (ioc_status) {
6709 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6710 desc = "Config Page Invalid Action";
6713 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6714 desc = "Config Page Invalid Type";
6717 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6718 desc = "Config Page Invalid Page";
6721 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6722 desc = "Config Page Invalid Data";
6725 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6726 desc = "Config Page No Defaults";
6729 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6730 desc = "Config Page Can't Commit";
6737 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
6738 ioc->name, ioc_status, desc, extend_desc);
6742 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
6743 * @ioc: Pointer to MPT_ADAPTER structure
6744 * @ioc_status: U32 IOCStatus word from IOC
6745 * @mf: Pointer to MPT request frame
6747 * Refer to lsi/mpi.h.
6750 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6752 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6757 /****************************************************************************/
6758 /* Common IOCStatus values for all replies */
6759 /****************************************************************************/
6761 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6762 desc = "Invalid Function";
6765 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6769 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6770 desc = "Invalid SGL";
6773 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6774 desc = "Internal Error";
6777 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6781 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6782 desc = "Insufficient Resources";
6785 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6786 desc = "Invalid Field";
6789 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6790 desc = "Invalid State";
6793 /****************************************************************************/
6794 /* Config IOCStatus values */
6795 /****************************************************************************/
6797 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6798 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6799 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6800 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6801 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6802 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6803 mpt_iocstatus_info_config(ioc, status, mf);
6806 /****************************************************************************/
6807 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
6809 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
6811 /****************************************************************************/
6813 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6814 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6815 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6816 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6817 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6818 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6819 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6820 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6821 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6822 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6823 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6824 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6825 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6828 /****************************************************************************/
6829 /* SCSI Target values */
6830 /****************************************************************************/
6832 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
6833 desc = "Target: Priority IO";
6836 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
6837 desc = "Target: Invalid Port";
6840 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
6841 desc = "Target Invalid IO Index:";
6844 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
6845 desc = "Target: Aborted";
6848 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
6849 desc = "Target: No Conn Retryable";
6852 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
6853 desc = "Target: No Connection";
6856 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
6857 desc = "Target: Transfer Count Mismatch";
6860 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
6861 desc = "Target: STS Data not Sent";
6864 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
6865 desc = "Target: Data Offset Error";
6868 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
6869 desc = "Target: Too Much Write Data";
6872 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
6873 desc = "Target: IU Too Short";
6876 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
6877 desc = "Target: ACK NAK Timeout";
6880 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
6881 desc = "Target: Nak Received";
6884 /****************************************************************************/
6885 /* Fibre Channel Direct Access values */
6886 /****************************************************************************/
6888 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
6889 desc = "FC: Aborted";
6892 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
6893 desc = "FC: RX ID Invalid";
6896 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
6897 desc = "FC: DID Invalid";
6900 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
6901 desc = "FC: Node Logged Out";
6904 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
6905 desc = "FC: Exchange Canceled";
6908 /****************************************************************************/
6910 /****************************************************************************/
6912 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
6913 desc = "LAN: Device not Found";
6916 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
6917 desc = "LAN: Device Failure";
6920 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
6921 desc = "LAN: Transmit Error";
6924 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
6925 desc = "LAN: Transmit Aborted";
6928 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
6929 desc = "LAN: Receive Error";
6932 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
6933 desc = "LAN: Receive Aborted";
6936 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
6937 desc = "LAN: Partial Packet";
6940 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
6941 desc = "LAN: Canceled";
6944 /****************************************************************************/
6945 /* Serial Attached SCSI values */
6946 /****************************************************************************/
6948 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
6949 desc = "SAS: SMP Request Failed";
6952 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
6953 desc = "SAS: SMP Data Overrun";
6964 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
6968 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6969 EXPORT_SYMBOL(mpt_attach);
6970 EXPORT_SYMBOL(mpt_detach);
6972 EXPORT_SYMBOL(mpt_resume);
6973 EXPORT_SYMBOL(mpt_suspend);
6975 EXPORT_SYMBOL(ioc_list);
6976 EXPORT_SYMBOL(mpt_proc_root_dir);
6977 EXPORT_SYMBOL(mpt_register);
6978 EXPORT_SYMBOL(mpt_deregister);
6979 EXPORT_SYMBOL(mpt_event_register);
6980 EXPORT_SYMBOL(mpt_event_deregister);
6981 EXPORT_SYMBOL(mpt_reset_register);
6982 EXPORT_SYMBOL(mpt_reset_deregister);
6983 EXPORT_SYMBOL(mpt_device_driver_register);
6984 EXPORT_SYMBOL(mpt_device_driver_deregister);
6985 EXPORT_SYMBOL(mpt_get_msg_frame);
6986 EXPORT_SYMBOL(mpt_put_msg_frame);
6987 EXPORT_SYMBOL(mpt_free_msg_frame);
6988 EXPORT_SYMBOL(mpt_add_sge);
6989 EXPORT_SYMBOL(mpt_send_handshake_request);
6990 EXPORT_SYMBOL(mpt_verify_adapter);
6991 EXPORT_SYMBOL(mpt_GetIocState);
6992 EXPORT_SYMBOL(mpt_print_ioc_summary);
6993 EXPORT_SYMBOL(mpt_lan_index);
6994 EXPORT_SYMBOL(mpt_stm_index);
6995 EXPORT_SYMBOL(mpt_HardResetHandler);
6996 EXPORT_SYMBOL(mpt_config);
6997 EXPORT_SYMBOL(mpt_findImVolumes);
6998 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6999 EXPORT_SYMBOL(mpt_free_fw_memory);
7000 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7001 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7003 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7005 * fusion_init - Fusion MPT base driver initialization routine.
7007 * Returns 0 for success, non-zero for failure.
7014 show_mptmod_ver(my_NAME, my_VERSION);
7015 printk(KERN_INFO COPYRIGHT "\n");
7017 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
7018 MptCallbacks[i] = NULL;
7019 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
7020 MptEvHandlers[i] = NULL;
7021 MptResetHandlers[i] = NULL;
7024 /* Register ourselves (mptbase) in order to facilitate
7025 * EventNotification handling.
7027 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7029 /* Register for hard reset handling callbacks.
7031 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
7032 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
7037 #ifdef CONFIG_PROC_FS
7038 (void) procmpt_create();
7043 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7045 * fusion_exit - Perform driver unload cleanup.
7047 * This routine frees all resources associated with each MPT adapter
7048 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7054 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
7056 mpt_reset_deregister(mpt_base_index);
7058 #ifdef CONFIG_PROC_FS
7063 module_init(fusion_init);
7064 module_exit(fusion_exit);