[SCSI] mptfusion: Set fw_events_off to 1 at driver load time.
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / message / fusion / mptbase.c
blob49005e151058d65497984cb6e49acd6a29a05d2b
1 /*
2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@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.
23 NO WARRANTY
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
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>
61 #include <asm/io.h>
62 #ifdef CONFIG_MTRR
63 #include <asm/mtrr.h>
64 #endif
66 #include "mptbase.h"
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
80 * cmd line parameters
83 static int mpt_msi_enable_spi;
84 module_param(mpt_msi_enable_spi, int, 0);
85 MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
86 controllers (default=0)");
88 static int mpt_msi_enable_fc;
89 module_param(mpt_msi_enable_fc, int, 0);
90 MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
91 controllers (default=0)");
93 static int mpt_msi_enable_sas;
94 module_param(mpt_msi_enable_sas, int, 0);
95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
96 controllers (default=0)");
99 static int mpt_channel_mapping;
100 module_param(mpt_channel_mapping, int, 0);
101 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
103 static int mpt_debug_level;
104 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
105 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
106 &mpt_debug_level, 0600);
107 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
108 - (default=0)");
110 int mpt_fwfault_debug;
111 EXPORT_SYMBOL(mpt_fwfault_debug);
112 module_param_call(mpt_fwfault_debug, param_set_int, param_get_int,
113 &mpt_fwfault_debug, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
119 #ifdef MFCNT
120 static int mfcounter = 0;
121 #define PRINT_MF_COUNT 20000
122 #endif
124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
126 * Public data...
129 #define WHOINIT_UNKNOWN 0xAA
131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
133 * Private data...
135 /* Adapter link list */
136 LIST_HEAD(ioc_list);
137 /* Callback lookup table */
138 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
139 /* Protocol driver class lookup table */
140 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
141 /* Event handler lookup table */
142 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
143 /* Reset handler lookup table */
144 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
145 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147 #ifdef CONFIG_PROC_FS
148 static struct proc_dir_entry *mpt_proc_root_dir;
149 #endif
152 * Driver Callback Index's
154 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
155 static u8 last_drv_idx;
157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
159 * Forward protos...
161 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
162 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
163 MPT_FRAME_HDR *reply);
164 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
165 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
166 int sleepFlag);
167 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
168 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
169 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
170 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
172 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
173 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
174 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
175 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
176 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
177 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
178 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
179 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
180 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
181 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
182 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
183 static int PrimeIocFifos(MPT_ADAPTER *ioc);
184 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
187 static int GetLanConfigPages(MPT_ADAPTER *ioc);
188 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
189 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
190 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
191 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
192 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
193 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
194 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
195 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
196 int sleepFlag);
197 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
198 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
199 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
201 #ifdef CONFIG_PROC_FS
202 static int procmpt_summary_read(char *buf, char **start, off_t offset,
203 int request, int *eof, void *data);
204 static int procmpt_version_read(char *buf, char **start, off_t offset,
205 int request, int *eof, void *data);
206 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
207 int request, int *eof, void *data);
208 #endif
209 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
211 static int ProcessEventNotification(MPT_ADAPTER *ioc,
212 EventNotificationReply_t *evReply, int *evHandlers);
213 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
214 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
215 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
216 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
217 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
218 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
220 /* module entry point */
221 static int __init fusion_init (void);
222 static void __exit fusion_exit (void);
224 #define CHIPREG_READ32(addr) readl_relaxed(addr)
225 #define CHIPREG_READ32_dmasync(addr) readl(addr)
226 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
227 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
228 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
230 static void
231 pci_disable_io_access(struct pci_dev *pdev)
233 u16 command_reg;
235 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
236 command_reg &= ~1;
237 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
240 static void
241 pci_enable_io_access(struct pci_dev *pdev)
243 u16 command_reg;
245 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
246 command_reg |= 1;
247 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
250 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
252 int ret = param_set_int(val, kp);
253 MPT_ADAPTER *ioc;
255 if (ret)
256 return ret;
258 list_for_each_entry(ioc, &ioc_list, list)
259 ioc->debug_level = mpt_debug_level;
260 return 0;
264 * mpt_get_cb_idx - obtain cb_idx for registered driver
265 * @dclass: class driver enum
267 * Returns cb_idx, or zero means it wasn't found
269 static u8
270 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
272 u8 cb_idx;
274 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
275 if (MptDriverClass[cb_idx] == dclass)
276 return cb_idx;
277 return 0;
281 * mpt_is_discovery_complete - determine if discovery has completed
282 * @ioc: per adatper instance
284 * Returns 1 when discovery completed, else zero.
286 static int
287 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
289 ConfigExtendedPageHeader_t hdr;
290 CONFIGPARMS cfg;
291 SasIOUnitPage0_t *buffer;
292 dma_addr_t dma_handle;
293 int rc = 0;
295 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
296 memset(&cfg, 0, sizeof(CONFIGPARMS));
297 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
298 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
299 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
300 cfg.cfghdr.ehdr = &hdr;
301 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
303 if ((mpt_config(ioc, &cfg)))
304 goto out;
305 if (!hdr.ExtPageLength)
306 goto out;
308 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
309 &dma_handle);
310 if (!buffer)
311 goto out;
313 cfg.physAddr = dma_handle;
314 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
316 if ((mpt_config(ioc, &cfg)))
317 goto out_free_consistent;
319 if (!(buffer->PhyData[0].PortFlags &
320 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
321 rc = 1;
323 out_free_consistent:
324 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
325 buffer, dma_handle);
326 out:
327 return rc;
331 * mpt_fault_reset_work - work performed on workq after ioc fault
332 * @work: input argument, used to derive ioc
335 static void
336 mpt_fault_reset_work(struct work_struct *work)
338 MPT_ADAPTER *ioc =
339 container_of(work, MPT_ADAPTER, fault_reset_work.work);
340 u32 ioc_raw_state;
341 int rc;
342 unsigned long flags;
344 if (ioc->ioc_reset_in_progress || !ioc->active)
345 goto out;
347 ioc_raw_state = mpt_GetIocState(ioc, 0);
348 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
349 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
350 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
351 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
352 ioc->name, __func__);
353 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
354 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
355 __func__, (rc == 0) ? "success" : "failed");
356 ioc_raw_state = mpt_GetIocState(ioc, 0);
357 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
358 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
359 "reset (%04xh)\n", ioc->name, ioc_raw_state &
360 MPI_DOORBELL_DATA_MASK);
361 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
362 if ((mpt_is_discovery_complete(ioc))) {
363 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
364 "discovery_quiesce_io flag\n", ioc->name));
365 ioc->sas_discovery_quiesce_io = 0;
369 out:
371 * Take turns polling alternate controller
373 if (ioc->alt_ioc)
374 ioc = ioc->alt_ioc;
376 /* rearm the timer */
377 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
378 if (ioc->reset_work_q)
379 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
380 msecs_to_jiffies(MPT_POLLING_INTERVAL));
381 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
386 * Process turbo (context) reply...
388 static void
389 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
391 MPT_FRAME_HDR *mf = NULL;
392 MPT_FRAME_HDR *mr = NULL;
393 u16 req_idx = 0;
394 u8 cb_idx;
396 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
397 ioc->name, pa));
399 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
400 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
401 req_idx = pa & 0x0000FFFF;
402 cb_idx = (pa & 0x00FF0000) >> 16;
403 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
404 break;
405 case MPI_CONTEXT_REPLY_TYPE_LAN:
406 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
408 * Blind set of mf to NULL here was fatal
409 * after lan_reply says "freeme"
410 * Fix sort of combined with an optimization here;
411 * added explicit check for case where lan_reply
412 * was just returning 1 and doing nothing else.
413 * For this case skip the callback, but set up
414 * proper mf value first here:-)
416 if ((pa & 0x58000000) == 0x58000000) {
417 req_idx = pa & 0x0000FFFF;
418 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
419 mpt_free_msg_frame(ioc, mf);
420 mb();
421 return;
422 break;
424 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
425 break;
426 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
427 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
428 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
429 break;
430 default:
431 cb_idx = 0;
432 BUG();
435 /* Check for (valid) IO callback! */
436 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
437 MptCallbacks[cb_idx] == NULL) {
438 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
439 __func__, ioc->name, cb_idx);
440 goto out;
443 if (MptCallbacks[cb_idx](ioc, mf, mr))
444 mpt_free_msg_frame(ioc, mf);
445 out:
446 mb();
449 static void
450 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
452 MPT_FRAME_HDR *mf;
453 MPT_FRAME_HDR *mr;
454 u16 req_idx;
455 u8 cb_idx;
456 int freeme;
458 u32 reply_dma_low;
459 u16 ioc_stat;
461 /* non-TURBO reply! Hmmm, something may be up...
462 * Newest turbo reply mechanism; get address
463 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
466 /* Map DMA address of reply header to cpu address.
467 * pa is 32 bits - but the dma address may be 32 or 64 bits
468 * get offset based only only the low addresses
471 reply_dma_low = (pa <<= 1);
472 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
473 (reply_dma_low - ioc->reply_frames_low_dma));
475 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
476 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
477 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
479 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
480 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
481 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
483 /* Check/log IOC log info
485 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
486 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
487 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
488 if (ioc->bus_type == FC)
489 mpt_fc_log_info(ioc, log_info);
490 else if (ioc->bus_type == SPI)
491 mpt_spi_log_info(ioc, log_info);
492 else if (ioc->bus_type == SAS)
493 mpt_sas_log_info(ioc, log_info);
496 if (ioc_stat & MPI_IOCSTATUS_MASK)
497 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
499 /* Check for (valid) IO callback! */
500 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
501 MptCallbacks[cb_idx] == NULL) {
502 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
503 __func__, ioc->name, cb_idx);
504 freeme = 0;
505 goto out;
508 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
510 out:
511 /* Flush (non-TURBO) reply with a WRITE! */
512 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
514 if (freeme)
515 mpt_free_msg_frame(ioc, mf);
516 mb();
519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
521 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
522 * @irq: irq number (not used)
523 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
525 * This routine is registered via the request_irq() kernel API call,
526 * and handles all interrupts generated from a specific MPT adapter
527 * (also referred to as a IO Controller or IOC).
528 * This routine must clear the interrupt from the adapter and does
529 * so by reading the reply FIFO. Multiple replies may be processed
530 * per single call to this routine.
532 * This routine handles register-level access of the adapter but
533 * dispatches (calls) a protocol-specific callback routine to handle
534 * the protocol-specific details of the MPT request completion.
536 static irqreturn_t
537 mpt_interrupt(int irq, void *bus_id)
539 MPT_ADAPTER *ioc = bus_id;
540 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
542 if (pa == 0xFFFFFFFF)
543 return IRQ_NONE;
546 * Drain the reply FIFO!
548 do {
549 if (pa & MPI_ADDRESS_REPLY_A_BIT)
550 mpt_reply(ioc, pa);
551 else
552 mpt_turbo_reply(ioc, pa);
553 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
554 } while (pa != 0xFFFFFFFF);
556 return IRQ_HANDLED;
559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
561 * mptbase_reply - MPT base driver's callback routine
562 * @ioc: Pointer to MPT_ADAPTER structure
563 * @req: Pointer to original MPT request frame
564 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
566 * MPT base driver's callback routine; all base driver
567 * "internal" request/reply processing is routed here.
568 * Currently used for EventNotification and EventAck handling.
570 * Returns 1 indicating original alloc'd request frame ptr
571 * should be freed, or 0 if it shouldn't.
573 static int
574 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
576 EventNotificationReply_t *pEventReply;
577 u8 event;
578 int evHandlers;
579 int freereq = 1;
581 switch (reply->u.hdr.Function) {
582 case MPI_FUNCTION_EVENT_NOTIFICATION:
583 pEventReply = (EventNotificationReply_t *)reply;
584 evHandlers = 0;
585 ProcessEventNotification(ioc, pEventReply, &evHandlers);
586 event = le32_to_cpu(pEventReply->Event) & 0xFF;
587 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
588 freereq = 0;
589 if (event != MPI_EVENT_EVENT_CHANGE)
590 break;
591 case MPI_FUNCTION_CONFIG:
592 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
593 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
594 if (reply) {
595 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
596 memcpy(ioc->mptbase_cmds.reply, reply,
597 min(MPT_DEFAULT_FRAME_SIZE,
598 4 * reply->u.reply.MsgLength));
600 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
601 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
602 complete(&ioc->mptbase_cmds.done);
603 } else
604 freereq = 0;
605 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
606 freereq = 1;
607 break;
608 case MPI_FUNCTION_EVENT_ACK:
609 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
610 "EventAck reply received\n", ioc->name));
611 break;
612 default:
613 printk(MYIOC_s_ERR_FMT
614 "Unexpected msg function (=%02Xh) reply received!\n",
615 ioc->name, reply->u.hdr.Function);
616 break;
620 * Conditionally tell caller to free the original
621 * EventNotification/EventAck/unexpected request frame!
623 return freereq;
626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
628 * mpt_register - Register protocol-specific main callback handler.
629 * @cbfunc: callback function pointer
630 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
632 * This routine is called by a protocol-specific driver (SCSI host,
633 * LAN, SCSI target) to register its reply callback routine. Each
634 * protocol-specific driver must do this before it will be able to
635 * use any IOC resources, such as obtaining request frames.
637 * NOTES: The SCSI protocol driver currently calls this routine thrice
638 * in order to register separate callbacks; one for "normal" SCSI IO;
639 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
641 * Returns u8 valued "handle" in the range (and S.O.D. order)
642 * {N,...,7,6,5,...,1} if successful.
643 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
644 * considered an error by the caller.
647 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
649 u8 cb_idx;
650 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
653 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
654 * (slot/handle 0 is reserved!)
656 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
657 if (MptCallbacks[cb_idx] == NULL) {
658 MptCallbacks[cb_idx] = cbfunc;
659 MptDriverClass[cb_idx] = dclass;
660 MptEvHandlers[cb_idx] = NULL;
661 last_drv_idx = cb_idx;
662 break;
666 return last_drv_idx;
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
671 * mpt_deregister - Deregister a protocol drivers resources.
672 * @cb_idx: previously registered callback handle
674 * Each protocol-specific driver should call this routine when its
675 * module is unloaded.
677 void
678 mpt_deregister(u8 cb_idx)
680 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
681 MptCallbacks[cb_idx] = NULL;
682 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
683 MptEvHandlers[cb_idx] = NULL;
685 last_drv_idx++;
689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
691 * mpt_event_register - Register protocol-specific event callback handler.
692 * @cb_idx: previously registered (via mpt_register) callback handle
693 * @ev_cbfunc: callback function
695 * This routine can be called by one or more protocol-specific drivers
696 * if/when they choose to be notified of MPT events.
698 * Returns 0 for success.
701 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
703 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
704 return -1;
706 MptEvHandlers[cb_idx] = ev_cbfunc;
707 return 0;
710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
712 * mpt_event_deregister - Deregister protocol-specific event callback handler
713 * @cb_idx: previously registered callback handle
715 * Each protocol-specific driver should call this routine
716 * when it does not (or can no longer) handle events,
717 * or when its module is unloaded.
719 void
720 mpt_event_deregister(u8 cb_idx)
722 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
723 return;
725 MptEvHandlers[cb_idx] = NULL;
728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
730 * mpt_reset_register - Register protocol-specific IOC reset handler.
731 * @cb_idx: previously registered (via mpt_register) callback handle
732 * @reset_func: reset function
734 * This routine can be called by one or more protocol-specific drivers
735 * if/when they choose to be notified of IOC resets.
737 * Returns 0 for success.
740 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
742 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
743 return -1;
745 MptResetHandlers[cb_idx] = reset_func;
746 return 0;
749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
751 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
752 * @cb_idx: previously registered callback handle
754 * Each protocol-specific driver should call this routine
755 * when it does not (or can no longer) handle IOC reset handling,
756 * or when its module is unloaded.
758 void
759 mpt_reset_deregister(u8 cb_idx)
761 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
762 return;
764 MptResetHandlers[cb_idx] = NULL;
767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
769 * mpt_device_driver_register - Register device driver hooks
770 * @dd_cbfunc: driver callbacks struct
771 * @cb_idx: MPT protocol driver index
774 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
776 MPT_ADAPTER *ioc;
777 const struct pci_device_id *id;
779 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
780 return -EINVAL;
782 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
784 /* call per pci device probe entry point */
785 list_for_each_entry(ioc, &ioc_list, list) {
786 id = ioc->pcidev->driver ?
787 ioc->pcidev->driver->id_table : NULL;
788 if (dd_cbfunc->probe)
789 dd_cbfunc->probe(ioc->pcidev, id);
792 return 0;
795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
797 * mpt_device_driver_deregister - DeRegister device driver hooks
798 * @cb_idx: MPT protocol driver index
800 void
801 mpt_device_driver_deregister(u8 cb_idx)
803 struct mpt_pci_driver *dd_cbfunc;
804 MPT_ADAPTER *ioc;
806 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
807 return;
809 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
811 list_for_each_entry(ioc, &ioc_list, list) {
812 if (dd_cbfunc->remove)
813 dd_cbfunc->remove(ioc->pcidev);
816 MptDeviceDriverHandlers[cb_idx] = NULL;
820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
822 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
823 * @cb_idx: Handle of registered MPT protocol driver
824 * @ioc: Pointer to MPT adapter structure
826 * Obtain an MPT request frame from the pool (of 1024) that are
827 * allocated per MPT adapter.
829 * Returns pointer to a MPT request frame or %NULL if none are available
830 * or IOC is not active.
832 MPT_FRAME_HDR*
833 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
835 MPT_FRAME_HDR *mf;
836 unsigned long flags;
837 u16 req_idx; /* Request index */
839 /* validate handle and ioc identifier */
841 #ifdef MFCNT
842 if (!ioc->active)
843 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
844 "returning NULL!\n", ioc->name);
845 #endif
847 /* If interrupts are not attached, do not return a request frame */
848 if (!ioc->active)
849 return NULL;
851 spin_lock_irqsave(&ioc->FreeQlock, flags);
852 if (!list_empty(&ioc->FreeQ)) {
853 int req_offset;
855 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
856 u.frame.linkage.list);
857 list_del(&mf->u.frame.linkage.list);
858 mf->u.frame.linkage.arg1 = 0;
859 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
860 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
861 /* u16! */
862 req_idx = req_offset / ioc->req_sz;
863 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
864 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
865 /* Default, will be changed if necessary in SG generation */
866 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
867 #ifdef MFCNT
868 ioc->mfcnt++;
869 #endif
871 else
872 mf = NULL;
873 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
875 #ifdef MFCNT
876 if (mf == NULL)
877 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
878 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
879 ioc->req_depth);
880 mfcounter++;
881 if (mfcounter == PRINT_MF_COUNT)
882 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
883 ioc->mfcnt, ioc->req_depth);
884 #endif
886 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
887 ioc->name, cb_idx, ioc->id, mf));
888 return mf;
891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
893 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
894 * @cb_idx: Handle of registered MPT protocol driver
895 * @ioc: Pointer to MPT adapter structure
896 * @mf: Pointer to MPT request frame
898 * This routine posts an MPT request frame to the request post FIFO of a
899 * specific MPT adapter.
901 void
902 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
904 u32 mf_dma_addr;
905 int req_offset;
906 u16 req_idx; /* Request index */
908 /* ensure values are reset properly! */
909 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
910 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
911 /* u16! */
912 req_idx = req_offset / ioc->req_sz;
913 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
914 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
916 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
918 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
919 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
920 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
921 ioc->RequestNB[req_idx]));
922 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
926 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
927 * @cb_idx: Handle of registered MPT protocol driver
928 * @ioc: Pointer to MPT adapter structure
929 * @mf: Pointer to MPT request frame
931 * Send a protocol-specific MPT request frame to an IOC using
932 * hi-priority request queue.
934 * This routine posts an MPT request frame to the request post FIFO of a
935 * specific MPT adapter.
937 void
938 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
940 u32 mf_dma_addr;
941 int req_offset;
942 u16 req_idx; /* Request index */
944 /* ensure values are reset properly! */
945 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
946 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
947 req_idx = req_offset / ioc->req_sz;
948 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
949 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
951 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
953 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
954 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
955 ioc->name, mf_dma_addr, req_idx));
956 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
961 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
962 * @ioc: Pointer to MPT adapter structure
963 * @mf: Pointer to MPT request frame
965 * This routine places a MPT request frame back on the MPT adapter's
966 * FreeQ.
968 void
969 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
971 unsigned long flags;
973 /* Put Request back on FreeQ! */
974 spin_lock_irqsave(&ioc->FreeQlock, flags);
975 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
976 goto out;
977 /* signature to know if this mf is freed */
978 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
979 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
980 #ifdef MFCNT
981 ioc->mfcnt--;
982 #endif
983 out:
984 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
989 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
990 * @pAddr: virtual address for SGE
991 * @flagslength: SGE flags and data transfer length
992 * @dma_addr: Physical address
994 * This routine places a MPT request frame back on the MPT adapter's
995 * FreeQ.
997 static void
998 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1000 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1001 pSge->FlagsLength = cpu_to_le32(flagslength);
1002 pSge->Address = cpu_to_le32(dma_addr);
1006 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1007 * @pAddr: virtual address for SGE
1008 * @flagslength: SGE flags and data transfer length
1009 * @dma_addr: Physical address
1011 * This routine places a MPT request frame back on the MPT adapter's
1012 * FreeQ.
1014 static void
1015 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1017 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1018 pSge->Address.Low = cpu_to_le32
1019 (lower_32_bits(dma_addr));
1020 pSge->Address.High = cpu_to_le32
1021 (upper_32_bits(dma_addr));
1022 pSge->FlagsLength = cpu_to_le32
1023 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1027 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1028 * @pAddr: virtual address for SGE
1029 * @flagslength: SGE flags and data transfer length
1030 * @dma_addr: Physical address
1032 * This routine places a MPT request frame back on the MPT adapter's
1033 * FreeQ.
1035 static void
1036 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1038 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1039 u32 tmp;
1041 pSge->Address.Low = cpu_to_le32
1042 (lower_32_bits(dma_addr));
1043 tmp = (u32)(upper_32_bits(dma_addr));
1046 * 1078 errata workaround for the 36GB limitation
1048 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1049 flagslength |=
1050 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1051 tmp |= (1<<31);
1052 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1053 printk(KERN_DEBUG "1078 P0M2 addressing for "
1054 "addr = 0x%llx len = %d\n",
1055 (unsigned long long)dma_addr,
1056 MPI_SGE_LENGTH(flagslength));
1059 pSge->Address.High = cpu_to_le32(tmp);
1060 pSge->FlagsLength = cpu_to_le32(
1061 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1066 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1067 * @pAddr: virtual address for SGE
1068 * @next: nextChainOffset value (u32's)
1069 * @length: length of next SGL segment
1070 * @dma_addr: Physical address
1073 static void
1074 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1076 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1077 pChain->Length = cpu_to_le16(length);
1078 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1079 pChain->NextChainOffset = next;
1080 pChain->Address = cpu_to_le32(dma_addr);
1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1085 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1086 * @pAddr: virtual address for SGE
1087 * @next: nextChainOffset value (u32's)
1088 * @length: length of next SGL segment
1089 * @dma_addr: Physical address
1092 static void
1093 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1095 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1096 u32 tmp = dma_addr & 0xFFFFFFFF;
1098 pChain->Length = cpu_to_le16(length);
1099 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1100 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1102 pChain->NextChainOffset = next;
1104 pChain->Address.Low = cpu_to_le32(tmp);
1105 tmp = (u32)(upper_32_bits(dma_addr));
1106 pChain->Address.High = cpu_to_le32(tmp);
1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1111 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1112 * @cb_idx: Handle of registered MPT protocol driver
1113 * @ioc: Pointer to MPT adapter structure
1114 * @reqBytes: Size of the request in bytes
1115 * @req: Pointer to MPT request frame
1116 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1118 * This routine is used exclusively to send MptScsiTaskMgmt
1119 * requests since they are required to be sent via doorbell handshake.
1121 * NOTE: It is the callers responsibility to byte-swap fields in the
1122 * request which are greater than 1 byte in size.
1124 * Returns 0 for success, non-zero for failure.
1127 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1129 int r = 0;
1130 u8 *req_as_bytes;
1131 int ii;
1133 /* State is known to be good upon entering
1134 * this function so issue the bus reset
1135 * request.
1139 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1140 * setting cb_idx/req_idx. But ONLY if this request
1141 * is in proper (pre-alloc'd) request buffer range...
1143 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1144 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1145 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1146 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1147 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1150 /* Make sure there are no doorbells */
1151 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1153 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1154 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1155 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1157 /* Wait for IOC doorbell int */
1158 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1159 return ii;
1162 /* Read doorbell and check for active bit */
1163 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1164 return -5;
1166 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1167 ioc->name, ii));
1169 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1171 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1172 return -2;
1175 /* Send request via doorbell handshake */
1176 req_as_bytes = (u8 *) req;
1177 for (ii = 0; ii < reqBytes/4; ii++) {
1178 u32 word;
1180 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1181 (req_as_bytes[(ii*4) + 1] << 8) |
1182 (req_as_bytes[(ii*4) + 2] << 16) |
1183 (req_as_bytes[(ii*4) + 3] << 24));
1184 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1185 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1186 r = -3;
1187 break;
1191 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1192 r = 0;
1193 else
1194 r = -4;
1196 /* Make sure there are no doorbells */
1197 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1199 return r;
1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1204 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1205 * @ioc: Pointer to MPT adapter structure
1206 * @access_control_value: define bits below
1207 * @sleepFlag: Specifies whether the process can sleep
1209 * Provides mechanism for the host driver to control the IOC's
1210 * Host Page Buffer access.
1212 * Access Control Value - bits[15:12]
1213 * 0h Reserved
1214 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1215 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1216 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1218 * Returns 0 for success, non-zero for failure.
1221 static int
1222 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1224 int r = 0;
1226 /* return if in use */
1227 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1228 & MPI_DOORBELL_ACTIVE)
1229 return -1;
1231 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1233 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1234 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1235 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1236 (access_control_value<<12)));
1238 /* Wait for IOC to clear Doorbell Status bit */
1239 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1240 return -2;
1241 }else
1242 return 0;
1245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1247 * mpt_host_page_alloc - allocate system memory for the fw
1248 * @ioc: Pointer to pointer to IOC adapter
1249 * @ioc_init: Pointer to ioc init config page
1251 * If we already allocated memory in past, then resend the same pointer.
1252 * Returns 0 for success, non-zero for failure.
1254 static int
1255 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1257 char *psge;
1258 int flags_length;
1259 u32 host_page_buffer_sz=0;
1261 if(!ioc->HostPageBuffer) {
1263 host_page_buffer_sz =
1264 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1266 if(!host_page_buffer_sz)
1267 return 0; /* fw doesn't need any host buffers */
1269 /* spin till we get enough memory */
1270 while(host_page_buffer_sz > 0) {
1272 if((ioc->HostPageBuffer = pci_alloc_consistent(
1273 ioc->pcidev,
1274 host_page_buffer_sz,
1275 &ioc->HostPageBuffer_dma)) != NULL) {
1277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1278 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1279 ioc->name, ioc->HostPageBuffer,
1280 (u32)ioc->HostPageBuffer_dma,
1281 host_page_buffer_sz));
1282 ioc->alloc_total += host_page_buffer_sz;
1283 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1284 break;
1287 host_page_buffer_sz -= (4*1024);
1291 if(!ioc->HostPageBuffer) {
1292 printk(MYIOC_s_ERR_FMT
1293 "Failed to alloc memory for host_page_buffer!\n",
1294 ioc->name);
1295 return -999;
1298 psge = (char *)&ioc_init->HostPageBufferSGE;
1299 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1300 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1301 MPI_SGE_FLAGS_HOST_TO_IOC |
1302 MPI_SGE_FLAGS_END_OF_BUFFER;
1303 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1304 flags_length |= ioc->HostPageBuffer_sz;
1305 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1306 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1308 return 0;
1311 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1313 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1314 * @iocid: IOC unique identifier (integer)
1315 * @iocpp: Pointer to pointer to IOC adapter
1317 * Given a unique IOC identifier, set pointer to the associated MPT
1318 * adapter structure.
1320 * Returns iocid and sets iocpp if iocid is found.
1321 * Returns -1 if iocid is not found.
1324 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1326 MPT_ADAPTER *ioc;
1328 list_for_each_entry(ioc,&ioc_list,list) {
1329 if (ioc->id == iocid) {
1330 *iocpp =ioc;
1331 return iocid;
1335 *iocpp = NULL;
1336 return -1;
1340 * mpt_get_product_name - returns product string
1341 * @vendor: pci vendor id
1342 * @device: pci device id
1343 * @revision: pci revision id
1344 * @prod_name: string returned
1346 * Returns product string displayed when driver loads,
1347 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1350 static void
1351 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1353 char *product_str = NULL;
1355 if (vendor == PCI_VENDOR_ID_BROCADE) {
1356 switch (device)
1358 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1359 switch (revision)
1361 case 0x00:
1362 product_str = "BRE040 A0";
1363 break;
1364 case 0x01:
1365 product_str = "BRE040 A1";
1366 break;
1367 default:
1368 product_str = "BRE040";
1369 break;
1371 break;
1373 goto out;
1376 switch (device)
1378 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1379 product_str = "LSIFC909 B1";
1380 break;
1381 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1382 product_str = "LSIFC919 B0";
1383 break;
1384 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1385 product_str = "LSIFC929 B0";
1386 break;
1387 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1388 if (revision < 0x80)
1389 product_str = "LSIFC919X A0";
1390 else
1391 product_str = "LSIFC919XL A1";
1392 break;
1393 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1394 if (revision < 0x80)
1395 product_str = "LSIFC929X A0";
1396 else
1397 product_str = "LSIFC929XL A1";
1398 break;
1399 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1400 product_str = "LSIFC939X A1";
1401 break;
1402 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1403 product_str = "LSIFC949X A1";
1404 break;
1405 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1406 switch (revision)
1408 case 0x00:
1409 product_str = "LSIFC949E A0";
1410 break;
1411 case 0x01:
1412 product_str = "LSIFC949E A1";
1413 break;
1414 default:
1415 product_str = "LSIFC949E";
1416 break;
1418 break;
1419 case MPI_MANUFACTPAGE_DEVID_53C1030:
1420 switch (revision)
1422 case 0x00:
1423 product_str = "LSI53C1030 A0";
1424 break;
1425 case 0x01:
1426 product_str = "LSI53C1030 B0";
1427 break;
1428 case 0x03:
1429 product_str = "LSI53C1030 B1";
1430 break;
1431 case 0x07:
1432 product_str = "LSI53C1030 B2";
1433 break;
1434 case 0x08:
1435 product_str = "LSI53C1030 C0";
1436 break;
1437 case 0x80:
1438 product_str = "LSI53C1030T A0";
1439 break;
1440 case 0x83:
1441 product_str = "LSI53C1030T A2";
1442 break;
1443 case 0x87:
1444 product_str = "LSI53C1030T A3";
1445 break;
1446 case 0xc1:
1447 product_str = "LSI53C1020A A1";
1448 break;
1449 default:
1450 product_str = "LSI53C1030";
1451 break;
1453 break;
1454 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1455 switch (revision)
1457 case 0x03:
1458 product_str = "LSI53C1035 A2";
1459 break;
1460 case 0x04:
1461 product_str = "LSI53C1035 B0";
1462 break;
1463 default:
1464 product_str = "LSI53C1035";
1465 break;
1467 break;
1468 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1469 switch (revision)
1471 case 0x00:
1472 product_str = "LSISAS1064 A1";
1473 break;
1474 case 0x01:
1475 product_str = "LSISAS1064 A2";
1476 break;
1477 case 0x02:
1478 product_str = "LSISAS1064 A3";
1479 break;
1480 case 0x03:
1481 product_str = "LSISAS1064 A4";
1482 break;
1483 default:
1484 product_str = "LSISAS1064";
1485 break;
1487 break;
1488 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1489 switch (revision)
1491 case 0x00:
1492 product_str = "LSISAS1064E A0";
1493 break;
1494 case 0x01:
1495 product_str = "LSISAS1064E B0";
1496 break;
1497 case 0x02:
1498 product_str = "LSISAS1064E B1";
1499 break;
1500 case 0x04:
1501 product_str = "LSISAS1064E B2";
1502 break;
1503 case 0x08:
1504 product_str = "LSISAS1064E B3";
1505 break;
1506 default:
1507 product_str = "LSISAS1064E";
1508 break;
1510 break;
1511 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1512 switch (revision)
1514 case 0x00:
1515 product_str = "LSISAS1068 A0";
1516 break;
1517 case 0x01:
1518 product_str = "LSISAS1068 B0";
1519 break;
1520 case 0x02:
1521 product_str = "LSISAS1068 B1";
1522 break;
1523 default:
1524 product_str = "LSISAS1068";
1525 break;
1527 break;
1528 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1529 switch (revision)
1531 case 0x00:
1532 product_str = "LSISAS1068E A0";
1533 break;
1534 case 0x01:
1535 product_str = "LSISAS1068E B0";
1536 break;
1537 case 0x02:
1538 product_str = "LSISAS1068E B1";
1539 break;
1540 case 0x04:
1541 product_str = "LSISAS1068E B2";
1542 break;
1543 case 0x08:
1544 product_str = "LSISAS1068E B3";
1545 break;
1546 default:
1547 product_str = "LSISAS1068E";
1548 break;
1550 break;
1551 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1552 switch (revision)
1554 case 0x00:
1555 product_str = "LSISAS1078 A0";
1556 break;
1557 case 0x01:
1558 product_str = "LSISAS1078 B0";
1559 break;
1560 case 0x02:
1561 product_str = "LSISAS1078 C0";
1562 break;
1563 case 0x03:
1564 product_str = "LSISAS1078 C1";
1565 break;
1566 case 0x04:
1567 product_str = "LSISAS1078 C2";
1568 break;
1569 default:
1570 product_str = "LSISAS1078";
1571 break;
1573 break;
1576 out:
1577 if (product_str)
1578 sprintf(prod_name, "%s", product_str);
1582 * mpt_mapresources - map in memory mapped io
1583 * @ioc: Pointer to pointer to IOC adapter
1586 static int
1587 mpt_mapresources(MPT_ADAPTER *ioc)
1589 u8 __iomem *mem;
1590 int ii;
1591 resource_size_t mem_phys;
1592 unsigned long port;
1593 u32 msize;
1594 u32 psize;
1595 u8 revision;
1596 int r = -ENODEV;
1597 struct pci_dev *pdev;
1599 pdev = ioc->pcidev;
1600 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1601 if (pci_enable_device_mem(pdev)) {
1602 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1603 "failed\n", ioc->name);
1604 return r;
1606 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1607 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1608 "MEM failed\n", ioc->name);
1609 return r;
1612 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1614 if (sizeof(dma_addr_t) > 4) {
1615 const uint64_t required_mask = dma_get_required_mask
1616 (&pdev->dev);
1617 if (required_mask > DMA_BIT_MASK(32)
1618 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1619 && !pci_set_consistent_dma_mask(pdev,
1620 DMA_BIT_MASK(64))) {
1621 ioc->dma_mask = DMA_BIT_MASK(64);
1622 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1623 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1624 ioc->name));
1625 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1626 && !pci_set_consistent_dma_mask(pdev,
1627 DMA_BIT_MASK(32))) {
1628 ioc->dma_mask = DMA_BIT_MASK(32);
1629 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1630 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1631 ioc->name));
1632 } else {
1633 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1634 ioc->name, pci_name(pdev));
1635 return r;
1637 } else {
1638 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1639 && !pci_set_consistent_dma_mask(pdev,
1640 DMA_BIT_MASK(32))) {
1641 ioc->dma_mask = DMA_BIT_MASK(32);
1642 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1643 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1644 ioc->name));
1645 } else {
1646 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1647 ioc->name, pci_name(pdev));
1648 return r;
1652 mem_phys = msize = 0;
1653 port = psize = 0;
1654 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1655 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1656 if (psize)
1657 continue;
1658 /* Get I/O space! */
1659 port = pci_resource_start(pdev, ii);
1660 psize = pci_resource_len(pdev, ii);
1661 } else {
1662 if (msize)
1663 continue;
1664 /* Get memmap */
1665 mem_phys = pci_resource_start(pdev, ii);
1666 msize = pci_resource_len(pdev, ii);
1669 ioc->mem_size = msize;
1671 mem = NULL;
1672 /* Get logical ptr for PciMem0 space */
1673 /*mem = ioremap(mem_phys, msize);*/
1674 mem = ioremap(mem_phys, msize);
1675 if (mem == NULL) {
1676 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1677 " memory!\n", ioc->name);
1678 return -EINVAL;
1680 ioc->memmap = mem;
1681 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1682 ioc->name, mem, (unsigned long long)mem_phys));
1684 ioc->mem_phys = mem_phys;
1685 ioc->chip = (SYSIF_REGS __iomem *)mem;
1687 /* Save Port IO values in case we need to do downloadboot */
1688 ioc->pio_mem_phys = port;
1689 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1691 return 0;
1694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1696 * mpt_attach - Install a PCI intelligent MPT adapter.
1697 * @pdev: Pointer to pci_dev structure
1698 * @id: PCI device ID information
1700 * This routine performs all the steps necessary to bring the IOC of
1701 * a MPT adapter to a OPERATIONAL state. This includes registering
1702 * memory regions, registering the interrupt, and allocating request
1703 * and reply memory pools.
1705 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1706 * MPT adapter.
1708 * Returns 0 for success, non-zero for failure.
1710 * TODO: Add support for polled controllers
1713 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1715 MPT_ADAPTER *ioc;
1716 u8 cb_idx;
1717 int r = -ENODEV;
1718 u8 revision;
1719 u8 pcixcmd;
1720 static int mpt_ids = 0;
1721 #ifdef CONFIG_PROC_FS
1722 struct proc_dir_entry *dent, *ent;
1723 #endif
1725 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1726 if (ioc == NULL) {
1727 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1728 return -ENOMEM;
1731 ioc->id = mpt_ids++;
1732 sprintf(ioc->name, "ioc%d", ioc->id);
1733 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1736 * set initial debug level
1737 * (refer to mptdebug.h)
1740 ioc->debug_level = mpt_debug_level;
1741 if (mpt_debug_level)
1742 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1744 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1746 ioc->pcidev = pdev;
1747 if (mpt_mapresources(ioc)) {
1748 kfree(ioc);
1749 return r;
1753 * Setting up proper handlers for scatter gather handling
1755 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1756 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1757 ioc->add_sge = &mpt_add_sge_64bit_1078;
1758 else
1759 ioc->add_sge = &mpt_add_sge_64bit;
1760 ioc->add_chain = &mpt_add_chain_64bit;
1761 ioc->sg_addr_size = 8;
1762 } else {
1763 ioc->add_sge = &mpt_add_sge;
1764 ioc->add_chain = &mpt_add_chain;
1765 ioc->sg_addr_size = 4;
1767 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1769 ioc->alloc_total = sizeof(MPT_ADAPTER);
1770 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1771 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1773 ioc->pcidev = pdev;
1775 spin_lock_init(&ioc->taskmgmt_lock);
1776 mutex_init(&ioc->internal_cmds.mutex);
1777 init_completion(&ioc->internal_cmds.done);
1778 mutex_init(&ioc->mptbase_cmds.mutex);
1779 init_completion(&ioc->mptbase_cmds.done);
1780 mutex_init(&ioc->taskmgmt_cmds.mutex);
1781 init_completion(&ioc->taskmgmt_cmds.done);
1783 /* Initialize the event logging.
1785 ioc->eventTypes = 0; /* None */
1786 ioc->eventContext = 0;
1787 ioc->eventLogSize = 0;
1788 ioc->events = NULL;
1790 #ifdef MFCNT
1791 ioc->mfcnt = 0;
1792 #endif
1794 ioc->sh = NULL;
1795 ioc->cached_fw = NULL;
1797 /* Initilize SCSI Config Data structure
1799 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1801 /* Initialize the fc rport list head.
1803 INIT_LIST_HEAD(&ioc->fc_rports);
1805 /* Find lookup slot. */
1806 INIT_LIST_HEAD(&ioc->list);
1809 /* Initialize workqueue */
1810 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1812 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1813 "mpt_poll_%d", ioc->id);
1814 ioc->reset_work_q =
1815 create_singlethread_workqueue(ioc->reset_work_q_name);
1816 if (!ioc->reset_work_q) {
1817 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1818 ioc->name);
1819 pci_release_selected_regions(pdev, ioc->bars);
1820 kfree(ioc);
1821 return -ENOMEM;
1824 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1825 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1827 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1828 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1830 switch (pdev->device)
1832 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1833 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1834 ioc->errata_flag_1064 = 1;
1835 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1836 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1837 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1838 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1839 ioc->bus_type = FC;
1840 break;
1842 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1843 if (revision < XL_929) {
1844 /* 929X Chip Fix. Set Split transactions level
1845 * for PCIX. Set MOST bits to zero.
1847 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1848 pcixcmd &= 0x8F;
1849 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1850 } else {
1851 /* 929XL Chip Fix. Set MMRBC to 0x08.
1853 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1854 pcixcmd |= 0x08;
1855 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1857 ioc->bus_type = FC;
1858 break;
1860 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1861 /* 919X Chip Fix. Set Split transactions level
1862 * for PCIX. Set MOST bits to zero.
1864 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1865 pcixcmd &= 0x8F;
1866 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1867 ioc->bus_type = FC;
1868 break;
1870 case MPI_MANUFACTPAGE_DEVID_53C1030:
1871 /* 1030 Chip Fix. Disable Split transactions
1872 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1874 if (revision < C0_1030) {
1875 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1876 pcixcmd &= 0x8F;
1877 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1880 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1881 ioc->bus_type = SPI;
1882 break;
1884 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1885 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1886 ioc->errata_flag_1064 = 1;
1887 ioc->bus_type = SAS;
1888 break;
1890 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1891 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1892 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1893 ioc->bus_type = SAS;
1894 break;
1898 switch (ioc->bus_type) {
1900 case SAS:
1901 ioc->msi_enable = mpt_msi_enable_sas;
1902 break;
1904 case SPI:
1905 ioc->msi_enable = mpt_msi_enable_spi;
1906 break;
1908 case FC:
1909 ioc->msi_enable = mpt_msi_enable_fc;
1910 break;
1912 default:
1913 ioc->msi_enable = 0;
1914 break;
1917 ioc->fw_events_off = 1;
1919 if (ioc->errata_flag_1064)
1920 pci_disable_io_access(pdev);
1922 spin_lock_init(&ioc->FreeQlock);
1924 /* Disable all! */
1925 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1926 ioc->active = 0;
1927 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1929 /* Set IOC ptr in the pcidev's driver data. */
1930 pci_set_drvdata(ioc->pcidev, ioc);
1932 /* Set lookup ptr. */
1933 list_add_tail(&ioc->list, &ioc_list);
1935 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1937 mpt_detect_bound_ports(ioc, pdev);
1939 INIT_LIST_HEAD(&ioc->fw_event_list);
1940 spin_lock_init(&ioc->fw_event_lock);
1941 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1942 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1944 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1945 CAN_SLEEP)) != 0){
1946 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1947 ioc->name, r);
1949 list_del(&ioc->list);
1950 if (ioc->alt_ioc)
1951 ioc->alt_ioc->alt_ioc = NULL;
1952 iounmap(ioc->memmap);
1953 if (r != -5)
1954 pci_release_selected_regions(pdev, ioc->bars);
1956 destroy_workqueue(ioc->reset_work_q);
1957 ioc->reset_work_q = NULL;
1959 kfree(ioc);
1960 pci_set_drvdata(pdev, NULL);
1961 return r;
1964 /* call per device driver probe entry point */
1965 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1966 if(MptDeviceDriverHandlers[cb_idx] &&
1967 MptDeviceDriverHandlers[cb_idx]->probe) {
1968 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1972 #ifdef CONFIG_PROC_FS
1974 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1976 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1977 if (dent) {
1978 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1979 if (ent) {
1980 ent->read_proc = procmpt_iocinfo_read;
1981 ent->data = ioc;
1983 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1984 if (ent) {
1985 ent->read_proc = procmpt_summary_read;
1986 ent->data = ioc;
1989 #endif
1991 if (!ioc->alt_ioc)
1992 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1993 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1995 return 0;
1998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2000 * mpt_detach - Remove a PCI intelligent MPT adapter.
2001 * @pdev: Pointer to pci_dev structure
2004 void
2005 mpt_detach(struct pci_dev *pdev)
2007 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2008 char pname[32];
2009 u8 cb_idx;
2010 unsigned long flags;
2011 struct workqueue_struct *wq;
2014 * Stop polling ioc for fault condition
2016 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2017 wq = ioc->reset_work_q;
2018 ioc->reset_work_q = NULL;
2019 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2020 cancel_delayed_work(&ioc->fault_reset_work);
2021 destroy_workqueue(wq);
2023 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2024 wq = ioc->fw_event_q;
2025 ioc->fw_event_q = NULL;
2026 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2027 destroy_workqueue(wq);
2029 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2030 remove_proc_entry(pname, NULL);
2031 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2032 remove_proc_entry(pname, NULL);
2033 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2034 remove_proc_entry(pname, NULL);
2036 /* call per device driver remove entry point */
2037 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2038 if(MptDeviceDriverHandlers[cb_idx] &&
2039 MptDeviceDriverHandlers[cb_idx]->remove) {
2040 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2044 /* Disable interrupts! */
2045 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2047 ioc->active = 0;
2048 synchronize_irq(pdev->irq);
2050 /* Clear any lingering interrupt */
2051 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2053 CHIPREG_READ32(&ioc->chip->IntStatus);
2055 mpt_adapter_dispose(ioc);
2057 pci_set_drvdata(pdev, NULL);
2060 /**************************************************************************
2061 * Power Management
2063 #ifdef CONFIG_PM
2064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2066 * mpt_suspend - Fusion MPT base driver suspend routine.
2067 * @pdev: Pointer to pci_dev structure
2068 * @state: new state to enter
2071 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2073 u32 device_state;
2074 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2076 device_state = pci_choose_state(pdev, state);
2077 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2078 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2079 device_state);
2081 /* put ioc into READY_STATE */
2082 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2083 printk(MYIOC_s_ERR_FMT
2084 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2087 /* disable interrupts */
2088 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2089 ioc->active = 0;
2091 /* Clear any lingering interrupt */
2092 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2094 free_irq(ioc->pci_irq, ioc);
2095 if (ioc->msi_enable)
2096 pci_disable_msi(ioc->pcidev);
2097 ioc->pci_irq = -1;
2098 pci_save_state(pdev);
2099 pci_disable_device(pdev);
2100 pci_release_selected_regions(pdev, ioc->bars);
2101 pci_set_power_state(pdev, device_state);
2102 return 0;
2105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2107 * mpt_resume - Fusion MPT base driver resume routine.
2108 * @pdev: Pointer to pci_dev structure
2111 mpt_resume(struct pci_dev *pdev)
2113 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2114 u32 device_state = pdev->current_state;
2115 int recovery_state;
2116 int err;
2118 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2119 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2120 device_state);
2122 pci_set_power_state(pdev, PCI_D0);
2123 pci_enable_wake(pdev, PCI_D0, 0);
2124 pci_restore_state(pdev);
2125 ioc->pcidev = pdev;
2126 err = mpt_mapresources(ioc);
2127 if (err)
2128 return err;
2130 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2131 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2132 ioc->add_sge = &mpt_add_sge_64bit_1078;
2133 else
2134 ioc->add_sge = &mpt_add_sge_64bit;
2135 ioc->add_chain = &mpt_add_chain_64bit;
2136 ioc->sg_addr_size = 8;
2137 } else {
2139 ioc->add_sge = &mpt_add_sge;
2140 ioc->add_chain = &mpt_add_chain;
2141 ioc->sg_addr_size = 4;
2143 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2145 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2146 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2147 CHIPREG_READ32(&ioc->chip->Doorbell));
2150 * Errata workaround for SAS pci express:
2151 * Upon returning to the D0 state, the contents of the doorbell will be
2152 * stale data, and this will incorrectly signal to the host driver that
2153 * the firmware is ready to process mpt commands. The workaround is
2154 * to issue a diagnostic reset.
2156 if (ioc->bus_type == SAS && (pdev->device ==
2157 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2158 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2159 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2160 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2161 ioc->name);
2162 goto out;
2166 /* bring ioc to operational state */
2167 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2168 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2169 CAN_SLEEP);
2170 if (recovery_state != 0)
2171 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2172 "error:[%x]\n", ioc->name, recovery_state);
2173 else
2174 printk(MYIOC_s_INFO_FMT
2175 "pci-resume: success\n", ioc->name);
2176 out:
2177 return 0;
2180 #endif
2182 static int
2183 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2185 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2186 ioc->bus_type != SPI) ||
2187 (MptDriverClass[index] == MPTFC_DRIVER &&
2188 ioc->bus_type != FC) ||
2189 (MptDriverClass[index] == MPTSAS_DRIVER &&
2190 ioc->bus_type != SAS))
2191 /* make sure we only call the relevant reset handler
2192 * for the bus */
2193 return 0;
2194 return (MptResetHandlers[index])(ioc, reset_phase);
2197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2199 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2200 * @ioc: Pointer to MPT adapter structure
2201 * @reason: Event word / reason
2202 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2204 * This routine performs all the steps necessary to bring the IOC
2205 * to a OPERATIONAL state.
2207 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2208 * MPT adapter.
2210 * Returns:
2211 * 0 for success
2212 * -1 if failed to get board READY
2213 * -2 if READY but IOCFacts Failed
2214 * -3 if READY but PrimeIOCFifos Failed
2215 * -4 if READY but IOCInit Failed
2216 * -5 if failed to enable_device and/or request_selected_regions
2217 * -6 if failed to upload firmware
2219 static int
2220 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2222 int hard_reset_done = 0;
2223 int alt_ioc_ready = 0;
2224 int hard;
2225 int rc=0;
2226 int ii;
2227 int ret = 0;
2228 int reset_alt_ioc_active = 0;
2229 int irq_allocated = 0;
2230 u8 *a;
2232 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2233 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2235 /* Disable reply interrupts (also blocks FreeQ) */
2236 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2237 ioc->active = 0;
2239 if (ioc->alt_ioc) {
2240 if (ioc->alt_ioc->active ||
2241 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2242 reset_alt_ioc_active = 1;
2243 /* Disable alt-IOC's reply interrupts
2244 * (and FreeQ) for a bit
2246 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2247 0xFFFFFFFF);
2248 ioc->alt_ioc->active = 0;
2252 hard = 1;
2253 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2254 hard = 0;
2256 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2257 if (hard_reset_done == -4) {
2258 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2259 ioc->name);
2261 if (reset_alt_ioc_active && ioc->alt_ioc) {
2262 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2263 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2264 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2265 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2266 ioc->alt_ioc->active = 1;
2269 } else {
2270 printk(MYIOC_s_WARN_FMT
2271 "NOT READY WARNING!\n", ioc->name);
2273 ret = -1;
2274 goto out;
2277 /* hard_reset_done = 0 if a soft reset was performed
2278 * and 1 if a hard reset was performed.
2280 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2281 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2282 alt_ioc_ready = 1;
2283 else
2284 printk(MYIOC_s_WARN_FMT
2285 ": alt-ioc Not ready WARNING!\n",
2286 ioc->alt_ioc->name);
2289 for (ii=0; ii<5; ii++) {
2290 /* Get IOC facts! Allow 5 retries */
2291 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2292 break;
2296 if (ii == 5) {
2297 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2298 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2299 ret = -2;
2300 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2301 MptDisplayIocCapabilities(ioc);
2304 if (alt_ioc_ready) {
2305 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2306 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2307 "Initial Alt IocFacts failed rc=%x\n",
2308 ioc->name, rc));
2309 /* Retry - alt IOC was initialized once
2311 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2313 if (rc) {
2314 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2315 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2316 alt_ioc_ready = 0;
2317 reset_alt_ioc_active = 0;
2318 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2319 MptDisplayIocCapabilities(ioc->alt_ioc);
2323 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2324 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2325 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2326 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2327 IORESOURCE_IO);
2328 if (pci_enable_device(ioc->pcidev))
2329 return -5;
2330 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2331 "mpt"))
2332 return -5;
2336 * Device is reset now. It must have de-asserted the interrupt line
2337 * (if it was asserted) and it should be safe to register for the
2338 * interrupt now.
2340 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2341 ioc->pci_irq = -1;
2342 if (ioc->pcidev->irq) {
2343 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2344 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2345 ioc->name);
2346 else
2347 ioc->msi_enable = 0;
2348 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2349 IRQF_SHARED, ioc->name, ioc);
2350 if (rc < 0) {
2351 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2352 "interrupt %d!\n",
2353 ioc->name, ioc->pcidev->irq);
2354 if (ioc->msi_enable)
2355 pci_disable_msi(ioc->pcidev);
2356 ret = -EBUSY;
2357 goto out;
2359 irq_allocated = 1;
2360 ioc->pci_irq = ioc->pcidev->irq;
2361 pci_set_master(ioc->pcidev); /* ?? */
2362 pci_set_drvdata(ioc->pcidev, ioc);
2363 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2364 "installed at interrupt %d\n", ioc->name,
2365 ioc->pcidev->irq));
2369 /* Prime reply & request queues!
2370 * (mucho alloc's) Must be done prior to
2371 * init as upper addresses are needed for init.
2372 * If fails, continue with alt-ioc processing
2374 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2375 ioc->name));
2376 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2377 ret = -3;
2379 /* May need to check/upload firmware & data here!
2380 * If fails, continue with alt-ioc processing
2382 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2383 ioc->name));
2384 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2385 ret = -4;
2386 // NEW!
2387 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2388 printk(MYIOC_s_WARN_FMT
2389 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2390 ioc->alt_ioc->name, rc);
2391 alt_ioc_ready = 0;
2392 reset_alt_ioc_active = 0;
2395 if (alt_ioc_ready) {
2396 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2397 alt_ioc_ready = 0;
2398 reset_alt_ioc_active = 0;
2399 printk(MYIOC_s_WARN_FMT
2400 ": alt-ioc: (%d) init failure WARNING!\n",
2401 ioc->alt_ioc->name, rc);
2405 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2406 if (ioc->upload_fw) {
2407 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2408 "firmware upload required!\n", ioc->name));
2410 /* Controller is not operational, cannot do upload
2412 if (ret == 0) {
2413 rc = mpt_do_upload(ioc, sleepFlag);
2414 if (rc == 0) {
2415 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2417 * Maintain only one pointer to FW memory
2418 * so there will not be two attempt to
2419 * downloadboot onboard dual function
2420 * chips (mpt_adapter_disable,
2421 * mpt_diag_reset)
2423 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2424 "mpt_upload: alt_%s has cached_fw=%p \n",
2425 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2426 ioc->cached_fw = NULL;
2428 } else {
2429 printk(MYIOC_s_WARN_FMT
2430 "firmware upload failure!\n", ioc->name);
2431 ret = -6;
2437 /* Enable MPT base driver management of EventNotification
2438 * and EventAck handling.
2440 if ((ret == 0) && (!ioc->facts.EventState)) {
2441 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2442 "SendEventNotification\n",
2443 ioc->name));
2444 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2447 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2448 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2450 if (ret == 0) {
2451 /* Enable! (reply interrupt) */
2452 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2453 ioc->active = 1;
2455 if (rc == 0) { /* alt ioc */
2456 if (reset_alt_ioc_active && ioc->alt_ioc) {
2457 /* (re)Enable alt-IOC! (reply interrupt) */
2458 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2459 "reply irq re-enabled\n",
2460 ioc->alt_ioc->name));
2461 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2462 MPI_HIM_DIM);
2463 ioc->alt_ioc->active = 1;
2468 /* Add additional "reason" check before call to GetLanConfigPages
2469 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2470 * recursive scenario; GetLanConfigPages times out, timer expired
2471 * routine calls HardResetHandler, which calls into here again,
2472 * and we try GetLanConfigPages again...
2474 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2477 * Initalize link list for inactive raid volumes.
2479 mutex_init(&ioc->raid_data.inactive_list_mutex);
2480 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2482 switch (ioc->bus_type) {
2484 case SAS:
2485 /* clear persistency table */
2486 if(ioc->facts.IOCExceptions &
2487 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2488 ret = mptbase_sas_persist_operation(ioc,
2489 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2490 if(ret != 0)
2491 goto out;
2494 /* Find IM volumes
2496 mpt_findImVolumes(ioc);
2498 /* Check, and possibly reset, the coalescing value
2500 mpt_read_ioc_pg_1(ioc);
2502 break;
2504 case FC:
2505 if ((ioc->pfacts[0].ProtocolFlags &
2506 MPI_PORTFACTS_PROTOCOL_LAN) &&
2507 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2509 * Pre-fetch the ports LAN MAC address!
2510 * (LANPage1_t stuff)
2512 (void) GetLanConfigPages(ioc);
2513 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2514 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2515 "LanAddr = %02X:%02X:%02X"
2516 ":%02X:%02X:%02X\n",
2517 ioc->name, a[5], a[4],
2518 a[3], a[2], a[1], a[0]));
2520 break;
2522 case SPI:
2523 /* Get NVRAM and adapter maximums from SPP 0 and 2
2525 mpt_GetScsiPortSettings(ioc, 0);
2527 /* Get version and length of SDP 1
2529 mpt_readScsiDevicePageHeaders(ioc, 0);
2531 /* Find IM volumes
2533 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2534 mpt_findImVolumes(ioc);
2536 /* Check, and possibly reset, the coalescing value
2538 mpt_read_ioc_pg_1(ioc);
2540 mpt_read_ioc_pg_4(ioc);
2542 break;
2545 GetIoUnitPage2(ioc);
2546 mpt_get_manufacturing_pg_0(ioc);
2549 out:
2550 if ((ret != 0) && irq_allocated) {
2551 free_irq(ioc->pci_irq, ioc);
2552 if (ioc->msi_enable)
2553 pci_disable_msi(ioc->pcidev);
2555 return ret;
2558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2560 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2561 * @ioc: Pointer to MPT adapter structure
2562 * @pdev: Pointer to (struct pci_dev) structure
2564 * Search for PCI bus/dev_function which matches
2565 * PCI bus/dev_function (+/-1) for newly discovered 929,
2566 * 929X, 1030 or 1035.
2568 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2569 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2571 static void
2572 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2574 struct pci_dev *peer=NULL;
2575 unsigned int slot = PCI_SLOT(pdev->devfn);
2576 unsigned int func = PCI_FUNC(pdev->devfn);
2577 MPT_ADAPTER *ioc_srch;
2579 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2580 " searching for devfn match on %x or %x\n",
2581 ioc->name, pci_name(pdev), pdev->bus->number,
2582 pdev->devfn, func-1, func+1));
2584 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2585 if (!peer) {
2586 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2587 if (!peer)
2588 return;
2591 list_for_each_entry(ioc_srch, &ioc_list, list) {
2592 struct pci_dev *_pcidev = ioc_srch->pcidev;
2593 if (_pcidev == peer) {
2594 /* Paranoia checks */
2595 if (ioc->alt_ioc != NULL) {
2596 printk(MYIOC_s_WARN_FMT
2597 "Oops, already bound (%s <==> %s)!\n",
2598 ioc->name, ioc->name, ioc->alt_ioc->name);
2599 break;
2600 } else if (ioc_srch->alt_ioc != NULL) {
2601 printk(MYIOC_s_WARN_FMT
2602 "Oops, already bound (%s <==> %s)!\n",
2603 ioc_srch->name, ioc_srch->name,
2604 ioc_srch->alt_ioc->name);
2605 break;
2607 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2608 "FOUND! binding %s <==> %s\n",
2609 ioc->name, ioc->name, ioc_srch->name));
2610 ioc_srch->alt_ioc = ioc;
2611 ioc->alt_ioc = ioc_srch;
2614 pci_dev_put(peer);
2617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2619 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2620 * @ioc: Pointer to MPT adapter structure
2622 static void
2623 mpt_adapter_disable(MPT_ADAPTER *ioc)
2625 int sz;
2626 int ret;
2628 if (ioc->cached_fw != NULL) {
2629 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2630 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2631 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2632 ioc->cached_fw, CAN_SLEEP)) < 0) {
2633 printk(MYIOC_s_WARN_FMT
2634 ": firmware downloadboot failure (%d)!\n",
2635 ioc->name, ret);
2640 * Put the controller into ready state (if its not already)
2642 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2643 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2644 CAN_SLEEP)) {
2645 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2646 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2647 "reset failed to put ioc in ready state!\n",
2648 ioc->name, __func__);
2649 } else
2650 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2651 "failed!\n", ioc->name, __func__);
2655 /* Disable adapter interrupts! */
2656 synchronize_irq(ioc->pcidev->irq);
2657 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2658 ioc->active = 0;
2660 /* Clear any lingering interrupt */
2661 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2662 CHIPREG_READ32(&ioc->chip->IntStatus);
2664 if (ioc->alloc != NULL) {
2665 sz = ioc->alloc_sz;
2666 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2667 ioc->name, ioc->alloc, ioc->alloc_sz));
2668 pci_free_consistent(ioc->pcidev, sz,
2669 ioc->alloc, ioc->alloc_dma);
2670 ioc->reply_frames = NULL;
2671 ioc->req_frames = NULL;
2672 ioc->alloc = NULL;
2673 ioc->alloc_total -= sz;
2676 if (ioc->sense_buf_pool != NULL) {
2677 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2678 pci_free_consistent(ioc->pcidev, sz,
2679 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2680 ioc->sense_buf_pool = NULL;
2681 ioc->alloc_total -= sz;
2684 if (ioc->events != NULL){
2685 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2686 kfree(ioc->events);
2687 ioc->events = NULL;
2688 ioc->alloc_total -= sz;
2691 mpt_free_fw_memory(ioc);
2693 kfree(ioc->spi_data.nvram);
2694 mpt_inactive_raid_list_free(ioc);
2695 kfree(ioc->raid_data.pIocPg2);
2696 kfree(ioc->raid_data.pIocPg3);
2697 ioc->spi_data.nvram = NULL;
2698 ioc->raid_data.pIocPg3 = NULL;
2700 if (ioc->spi_data.pIocPg4 != NULL) {
2701 sz = ioc->spi_data.IocPg4Sz;
2702 pci_free_consistent(ioc->pcidev, sz,
2703 ioc->spi_data.pIocPg4,
2704 ioc->spi_data.IocPg4_dma);
2705 ioc->spi_data.pIocPg4 = NULL;
2706 ioc->alloc_total -= sz;
2709 if (ioc->ReqToChain != NULL) {
2710 kfree(ioc->ReqToChain);
2711 kfree(ioc->RequestNB);
2712 ioc->ReqToChain = NULL;
2715 kfree(ioc->ChainToChain);
2716 ioc->ChainToChain = NULL;
2718 if (ioc->HostPageBuffer != NULL) {
2719 if((ret = mpt_host_page_access_control(ioc,
2720 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2721 printk(MYIOC_s_ERR_FMT
2722 ": %s: host page buffers free failed (%d)!\n",
2723 ioc->name, __func__, ret);
2725 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2726 "HostPageBuffer free @ %p, sz=%d bytes\n",
2727 ioc->name, ioc->HostPageBuffer,
2728 ioc->HostPageBuffer_sz));
2729 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2730 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2731 ioc->HostPageBuffer = NULL;
2732 ioc->HostPageBuffer_sz = 0;
2733 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2736 pci_set_drvdata(ioc->pcidev, NULL);
2738 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2740 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2741 * @ioc: Pointer to MPT adapter structure
2743 * This routine unregisters h/w resources and frees all alloc'd memory
2744 * associated with a MPT adapter structure.
2746 static void
2747 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2749 int sz_first, sz_last;
2751 if (ioc == NULL)
2752 return;
2754 sz_first = ioc->alloc_total;
2756 mpt_adapter_disable(ioc);
2758 if (ioc->pci_irq != -1) {
2759 free_irq(ioc->pci_irq, ioc);
2760 if (ioc->msi_enable)
2761 pci_disable_msi(ioc->pcidev);
2762 ioc->pci_irq = -1;
2765 if (ioc->memmap != NULL) {
2766 iounmap(ioc->memmap);
2767 ioc->memmap = NULL;
2770 pci_disable_device(ioc->pcidev);
2771 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2773 #if defined(CONFIG_MTRR) && 0
2774 if (ioc->mtrr_reg > 0) {
2775 mtrr_del(ioc->mtrr_reg, 0, 0);
2776 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2778 #endif
2780 /* Zap the adapter lookup ptr! */
2781 list_del(&ioc->list);
2783 sz_last = ioc->alloc_total;
2784 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2785 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2787 if (ioc->alt_ioc)
2788 ioc->alt_ioc->alt_ioc = NULL;
2790 kfree(ioc);
2793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2795 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2796 * @ioc: Pointer to MPT adapter structure
2798 static void
2799 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2801 int i = 0;
2803 printk(KERN_INFO "%s: ", ioc->name);
2804 if (ioc->prod_name)
2805 printk("%s: ", ioc->prod_name);
2806 printk("Capabilities={");
2808 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2809 printk("Initiator");
2810 i++;
2813 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2814 printk("%sTarget", i ? "," : "");
2815 i++;
2818 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2819 printk("%sLAN", i ? "," : "");
2820 i++;
2823 #if 0
2825 * This would probably evoke more questions than it's worth
2827 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2828 printk("%sLogBusAddr", i ? "," : "");
2829 i++;
2831 #endif
2833 printk("}\n");
2836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2838 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2839 * @ioc: Pointer to MPT_ADAPTER structure
2840 * @force: Force hard KickStart of IOC
2841 * @sleepFlag: Specifies whether the process can sleep
2843 * Returns:
2844 * 1 - DIAG reset and READY
2845 * 0 - READY initially OR soft reset and READY
2846 * -1 - Any failure on KickStart
2847 * -2 - Msg Unit Reset Failed
2848 * -3 - IO Unit Reset Failed
2849 * -4 - IOC owned by a PEER
2851 static int
2852 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2854 u32 ioc_state;
2855 int statefault = 0;
2856 int cntdn;
2857 int hard_reset_done = 0;
2858 int r;
2859 int ii;
2860 int whoinit;
2862 /* Get current [raw] IOC state */
2863 ioc_state = mpt_GetIocState(ioc, 0);
2864 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2867 * Check to see if IOC got left/stuck in doorbell handshake
2868 * grip of death. If so, hard reset the IOC.
2870 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2871 statefault = 1;
2872 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2873 ioc->name);
2876 /* Is it already READY? */
2877 if (!statefault &&
2878 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2879 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2880 "IOC is in READY state\n", ioc->name));
2881 return 0;
2885 * Check to see if IOC is in FAULT state.
2887 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2888 statefault = 2;
2889 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2890 ioc->name);
2891 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2892 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2896 * Hmmm... Did it get left operational?
2898 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2899 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2900 ioc->name));
2902 /* Check WhoInit.
2903 * If PCI Peer, exit.
2904 * Else, if no fault conditions are present, issue a MessageUnitReset
2905 * Else, fall through to KickStart case
2907 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2908 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2909 "whoinit 0x%x statefault %d force %d\n",
2910 ioc->name, whoinit, statefault, force));
2911 if (whoinit == MPI_WHOINIT_PCI_PEER)
2912 return -4;
2913 else {
2914 if ((statefault == 0 ) && (force == 0)) {
2915 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2916 return 0;
2918 statefault = 3;
2922 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2923 if (hard_reset_done < 0)
2924 return -1;
2927 * Loop here waiting for IOC to come READY.
2929 ii = 0;
2930 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2932 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2933 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2935 * BIOS or previous driver load left IOC in OP state.
2936 * Reset messaging FIFOs.
2938 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2939 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2940 return -2;
2942 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2944 * Something is wrong. Try to get IOC back
2945 * to a known state.
2947 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2948 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2949 return -3;
2953 ii++; cntdn--;
2954 if (!cntdn) {
2955 printk(MYIOC_s_ERR_FMT
2956 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2957 ioc->name, ioc_state, (int)((ii+5)/HZ));
2958 return -ETIME;
2961 if (sleepFlag == CAN_SLEEP) {
2962 msleep(1);
2963 } else {
2964 mdelay (1); /* 1 msec delay */
2969 if (statefault < 3) {
2970 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
2971 statefault == 1 ? "stuck handshake" : "IOC FAULT");
2974 return hard_reset_done;
2977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2979 * mpt_GetIocState - Get the current state of a MPT adapter.
2980 * @ioc: Pointer to MPT_ADAPTER structure
2981 * @cooked: Request raw or cooked IOC state
2983 * Returns all IOC Doorbell register bits if cooked==0, else just the
2984 * Doorbell bits in MPI_IOC_STATE_MASK.
2987 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2989 u32 s, sc;
2991 /* Get! */
2992 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2993 sc = s & MPI_IOC_STATE_MASK;
2995 /* Save! */
2996 ioc->last_state = sc;
2998 return cooked ? sc : s;
3001 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3003 * GetIocFacts - Send IOCFacts request to MPT adapter.
3004 * @ioc: Pointer to MPT_ADAPTER structure
3005 * @sleepFlag: Specifies whether the process can sleep
3006 * @reason: If recovery, only update facts.
3008 * Returns 0 for success, non-zero for failure.
3010 static int
3011 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3013 IOCFacts_t get_facts;
3014 IOCFactsReply_t *facts;
3015 int r;
3016 int req_sz;
3017 int reply_sz;
3018 int sz;
3019 u32 status, vv;
3020 u8 shiftFactor=1;
3022 /* IOC *must* NOT be in RESET state! */
3023 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3024 printk(KERN_ERR MYNAM
3025 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3026 ioc->name, ioc->last_state);
3027 return -44;
3030 facts = &ioc->facts;
3032 /* Destination (reply area)... */
3033 reply_sz = sizeof(*facts);
3034 memset(facts, 0, reply_sz);
3036 /* Request area (get_facts on the stack right now!) */
3037 req_sz = sizeof(get_facts);
3038 memset(&get_facts, 0, req_sz);
3040 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3041 /* Assert: All other get_facts fields are zero! */
3043 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3044 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3045 ioc->name, req_sz, reply_sz));
3047 /* No non-zero fields in the get_facts request are greater than
3048 * 1 byte in size, so we can just fire it off as is.
3050 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3051 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3052 if (r != 0)
3053 return r;
3056 * Now byte swap (GRRR) the necessary fields before any further
3057 * inspection of reply contents.
3059 * But need to do some sanity checks on MsgLength (byte) field
3060 * to make sure we don't zero IOC's req_sz!
3062 /* Did we get a valid reply? */
3063 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3064 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3066 * If not been here, done that, save off first WhoInit value
3068 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3069 ioc->FirstWhoInit = facts->WhoInit;
3072 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3073 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3074 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3075 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3076 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3077 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3078 /* CHECKME! IOCStatus, IOCLogInfo */
3080 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3081 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3084 * FC f/w version changed between 1.1 and 1.2
3085 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3086 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3088 if (facts->MsgVersion < MPI_VERSION_01_02) {
3090 * Handle old FC f/w style, convert to new...
3092 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3093 facts->FWVersion.Word =
3094 ((oldv<<12) & 0xFF000000) |
3095 ((oldv<<8) & 0x000FFF00);
3096 } else
3097 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3099 facts->ProductID = le16_to_cpu(facts->ProductID);
3101 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3102 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3103 ioc->ir_firmware = 1;
3105 facts->CurrentHostMfaHighAddr =
3106 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3107 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3108 facts->CurrentSenseBufferHighAddr =
3109 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3110 facts->CurReplyFrameSize =
3111 le16_to_cpu(facts->CurReplyFrameSize);
3112 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3115 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3116 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3117 * to 14 in MPI-1.01.0x.
3119 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3120 facts->MsgVersion > MPI_VERSION_01_00) {
3121 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3124 sz = facts->FWImageSize;
3125 if ( sz & 0x01 )
3126 sz += 1;
3127 if ( sz & 0x02 )
3128 sz += 2;
3129 facts->FWImageSize = sz;
3131 if (!facts->RequestFrameSize) {
3132 /* Something is wrong! */
3133 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3134 ioc->name);
3135 return -55;
3138 r = sz = facts->BlockSize;
3139 vv = ((63 / (sz * 4)) + 1) & 0x03;
3140 ioc->NB_for_64_byte_frame = vv;
3141 while ( sz )
3143 shiftFactor++;
3144 sz = sz >> 1;
3146 ioc->NBShiftFactor = shiftFactor;
3147 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3148 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3149 ioc->name, vv, shiftFactor, r));
3151 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3153 * Set values for this IOC's request & reply frame sizes,
3154 * and request & reply queue depths...
3156 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3157 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3158 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3159 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3161 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3162 ioc->name, ioc->reply_sz, ioc->reply_depth));
3163 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3164 ioc->name, ioc->req_sz, ioc->req_depth));
3166 /* Get port facts! */
3167 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3168 return r;
3170 } else {
3171 printk(MYIOC_s_ERR_FMT
3172 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3173 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3174 RequestFrameSize)/sizeof(u32)));
3175 return -66;
3178 return 0;
3181 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3183 * GetPortFacts - Send PortFacts request to MPT adapter.
3184 * @ioc: Pointer to MPT_ADAPTER structure
3185 * @portnum: Port number
3186 * @sleepFlag: Specifies whether the process can sleep
3188 * Returns 0 for success, non-zero for failure.
3190 static int
3191 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3193 PortFacts_t get_pfacts;
3194 PortFactsReply_t *pfacts;
3195 int ii;
3196 int req_sz;
3197 int reply_sz;
3198 int max_id;
3200 /* IOC *must* NOT be in RESET state! */
3201 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3202 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3203 ioc->name, ioc->last_state );
3204 return -4;
3207 pfacts = &ioc->pfacts[portnum];
3209 /* Destination (reply area)... */
3210 reply_sz = sizeof(*pfacts);
3211 memset(pfacts, 0, reply_sz);
3213 /* Request area (get_pfacts on the stack right now!) */
3214 req_sz = sizeof(get_pfacts);
3215 memset(&get_pfacts, 0, req_sz);
3217 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3218 get_pfacts.PortNumber = portnum;
3219 /* Assert: All other get_pfacts fields are zero! */
3221 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3222 ioc->name, portnum));
3224 /* No non-zero fields in the get_pfacts request are greater than
3225 * 1 byte in size, so we can just fire it off as is.
3227 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3228 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3229 if (ii != 0)
3230 return ii;
3232 /* Did we get a valid reply? */
3234 /* Now byte swap the necessary fields in the response. */
3235 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3236 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3237 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3238 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3239 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3240 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3241 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3242 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3243 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3245 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3246 pfacts->MaxDevices;
3247 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3248 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3251 * Place all the devices on channels
3253 * (for debuging)
3255 if (mpt_channel_mapping) {
3256 ioc->devices_per_bus = 1;
3257 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3260 return 0;
3263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3265 * SendIocInit - Send IOCInit request to MPT adapter.
3266 * @ioc: Pointer to MPT_ADAPTER structure
3267 * @sleepFlag: Specifies whether the process can sleep
3269 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3271 * Returns 0 for success, non-zero for failure.
3273 static int
3274 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3276 IOCInit_t ioc_init;
3277 MPIDefaultReply_t init_reply;
3278 u32 state;
3279 int r;
3280 int count;
3281 int cntdn;
3283 memset(&ioc_init, 0, sizeof(ioc_init));
3284 memset(&init_reply, 0, sizeof(init_reply));
3286 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3287 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3289 /* If we are in a recovery mode and we uploaded the FW image,
3290 * then this pointer is not NULL. Skip the upload a second time.
3291 * Set this flag if cached_fw set for either IOC.
3293 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3294 ioc->upload_fw = 1;
3295 else
3296 ioc->upload_fw = 0;
3297 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3298 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3300 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3301 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3303 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3304 ioc->name, ioc->facts.MsgVersion));
3305 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3306 // set MsgVersion and HeaderVersion host driver was built with
3307 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3308 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3310 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3311 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3312 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3313 return -99;
3315 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3317 if (ioc->sg_addr_size == sizeof(u64)) {
3318 /* Save the upper 32-bits of the request
3319 * (reply) and sense buffers.
3321 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3322 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3323 } else {
3324 /* Force 32-bit addressing */
3325 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3326 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3329 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3330 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3331 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3332 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3334 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3335 ioc->name, &ioc_init));
3337 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3338 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3339 if (r != 0) {
3340 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3341 return r;
3344 /* No need to byte swap the multibyte fields in the reply
3345 * since we don't even look at its contents.
3348 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3349 ioc->name, &ioc_init));
3351 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3352 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3353 return r;
3356 /* YIKES! SUPER IMPORTANT!!!
3357 * Poll IocState until _OPERATIONAL while IOC is doing
3358 * LoopInit and TargetDiscovery!
3360 count = 0;
3361 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3362 state = mpt_GetIocState(ioc, 1);
3363 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3364 if (sleepFlag == CAN_SLEEP) {
3365 msleep(1);
3366 } else {
3367 mdelay(1);
3370 if (!cntdn) {
3371 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3372 ioc->name, (int)((count+5)/HZ));
3373 return -9;
3376 state = mpt_GetIocState(ioc, 1);
3377 count++;
3379 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3380 ioc->name, count));
3382 ioc->aen_event_read_flag=0;
3383 return r;
3386 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3388 * SendPortEnable - Send PortEnable request to MPT adapter port.
3389 * @ioc: Pointer to MPT_ADAPTER structure
3390 * @portnum: Port number to enable
3391 * @sleepFlag: Specifies whether the process can sleep
3393 * Send PortEnable to bring IOC to OPERATIONAL state.
3395 * Returns 0 for success, non-zero for failure.
3397 static int
3398 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3400 PortEnable_t port_enable;
3401 MPIDefaultReply_t reply_buf;
3402 int rc;
3403 int req_sz;
3404 int reply_sz;
3406 /* Destination... */
3407 reply_sz = sizeof(MPIDefaultReply_t);
3408 memset(&reply_buf, 0, reply_sz);
3410 req_sz = sizeof(PortEnable_t);
3411 memset(&port_enable, 0, req_sz);
3413 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3414 port_enable.PortNumber = portnum;
3415 /* port_enable.ChainOffset = 0; */
3416 /* port_enable.MsgFlags = 0; */
3417 /* port_enable.MsgContext = 0; */
3419 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3420 ioc->name, portnum, &port_enable));
3422 /* RAID FW may take a long time to enable
3424 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3425 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3426 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3427 300 /*seconds*/, sleepFlag);
3428 } else {
3429 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3430 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3431 30 /*seconds*/, sleepFlag);
3433 return rc;
3437 * mpt_alloc_fw_memory - allocate firmware memory
3438 * @ioc: Pointer to MPT_ADAPTER structure
3439 * @size: total FW bytes
3441 * If memory has already been allocated, the same (cached) value
3442 * is returned.
3444 * Return 0 if successfull, or non-zero for failure
3447 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3449 int rc;
3451 if (ioc->cached_fw) {
3452 rc = 0; /* use already allocated memory */
3453 goto out;
3455 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3456 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3457 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3458 rc = 0;
3459 goto out;
3461 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3462 if (!ioc->cached_fw) {
3463 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3464 ioc->name);
3465 rc = -1;
3466 } else {
3467 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3468 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3469 ioc->alloc_total += size;
3470 rc = 0;
3472 out:
3473 return rc;
3477 * mpt_free_fw_memory - free firmware memory
3478 * @ioc: Pointer to MPT_ADAPTER structure
3480 * If alt_img is NULL, delete from ioc structure.
3481 * Else, delete a secondary image in same format.
3483 void
3484 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3486 int sz;
3488 if (!ioc->cached_fw)
3489 return;
3491 sz = ioc->facts.FWImageSize;
3492 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3493 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3494 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3495 ioc->alloc_total -= sz;
3496 ioc->cached_fw = NULL;
3499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3501 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3502 * @ioc: Pointer to MPT_ADAPTER structure
3503 * @sleepFlag: Specifies whether the process can sleep
3505 * Returns 0 for success, >0 for handshake failure
3506 * <0 for fw upload failure.
3508 * Remark: If bound IOC and a successful FWUpload was performed
3509 * on the bound IOC, the second image is discarded
3510 * and memory is free'd. Both channels must upload to prevent
3511 * IOC from running in degraded mode.
3513 static int
3514 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3516 u8 reply[sizeof(FWUploadReply_t)];
3517 FWUpload_t *prequest;
3518 FWUploadReply_t *preply;
3519 FWUploadTCSGE_t *ptcsge;
3520 u32 flagsLength;
3521 int ii, sz, reply_sz;
3522 int cmdStatus;
3523 int request_size;
3524 /* If the image size is 0, we are done.
3526 if ((sz = ioc->facts.FWImageSize) == 0)
3527 return 0;
3529 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3530 return -ENOMEM;
3532 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3533 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3535 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3536 kzalloc(ioc->req_sz, GFP_KERNEL);
3537 if (!prequest) {
3538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3539 "while allocating memory \n", ioc->name));
3540 mpt_free_fw_memory(ioc);
3541 return -ENOMEM;
3544 preply = (FWUploadReply_t *)&reply;
3546 reply_sz = sizeof(reply);
3547 memset(preply, 0, reply_sz);
3549 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3550 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3552 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3553 ptcsge->DetailsLength = 12;
3554 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3555 ptcsge->ImageSize = cpu_to_le32(sz);
3556 ptcsge++;
3558 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3559 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3560 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3561 ioc->SGE_size;
3562 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3563 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3564 ioc->facts.FWImageSize, request_size));
3565 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3567 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3568 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3570 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3571 "rc=%x \n", ioc->name, ii));
3573 cmdStatus = -EFAULT;
3574 if (ii == 0) {
3575 /* Handshake transfer was complete and successful.
3576 * Check the Reply Frame.
3578 int status;
3579 status = le16_to_cpu(preply->IOCStatus) &
3580 MPI_IOCSTATUS_MASK;
3581 if (status == MPI_IOCSTATUS_SUCCESS &&
3582 ioc->facts.FWImageSize ==
3583 le32_to_cpu(preply->ActualImageSize))
3584 cmdStatus = 0;
3586 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3587 ioc->name, cmdStatus));
3590 if (cmdStatus) {
3591 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3592 "freeing image \n", ioc->name));
3593 mpt_free_fw_memory(ioc);
3595 kfree(prequest);
3597 return cmdStatus;
3600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3602 * mpt_downloadboot - DownloadBoot code
3603 * @ioc: Pointer to MPT_ADAPTER structure
3604 * @pFwHeader: Pointer to firmware header info
3605 * @sleepFlag: Specifies whether the process can sleep
3607 * FwDownloadBoot requires Programmed IO access.
3609 * Returns 0 for success
3610 * -1 FW Image size is 0
3611 * -2 No valid cached_fw Pointer
3612 * <0 for fw upload failure.
3614 static int
3615 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3617 MpiExtImageHeader_t *pExtImage;
3618 u32 fwSize;
3619 u32 diag0val;
3620 int count;
3621 u32 *ptrFw;
3622 u32 diagRwData;
3623 u32 nextImage;
3624 u32 load_addr;
3625 u32 ioc_state=0;
3627 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3628 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3630 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3631 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3632 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3633 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3634 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3635 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3637 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3639 /* wait 1 msec */
3640 if (sleepFlag == CAN_SLEEP) {
3641 msleep(1);
3642 } else {
3643 mdelay (1);
3646 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3647 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3649 for (count = 0; count < 30; count ++) {
3650 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3651 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3652 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3653 ioc->name, count));
3654 break;
3656 /* wait .1 sec */
3657 if (sleepFlag == CAN_SLEEP) {
3658 msleep (100);
3659 } else {
3660 mdelay (100);
3664 if ( count == 30 ) {
3665 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3666 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3667 ioc->name, diag0val));
3668 return -3;
3671 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3672 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3673 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3674 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3675 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3676 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3678 /* Set the DiagRwEn and Disable ARM bits */
3679 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3681 fwSize = (pFwHeader->ImageSize + 3)/4;
3682 ptrFw = (u32 *) pFwHeader;
3684 /* Write the LoadStartAddress to the DiagRw Address Register
3685 * using Programmed IO
3687 if (ioc->errata_flag_1064)
3688 pci_enable_io_access(ioc->pcidev);
3690 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3691 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3692 ioc->name, pFwHeader->LoadStartAddress));
3694 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3695 ioc->name, fwSize*4, ptrFw));
3696 while (fwSize--) {
3697 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3700 nextImage = pFwHeader->NextImageHeaderOffset;
3701 while (nextImage) {
3702 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3704 load_addr = pExtImage->LoadStartAddress;
3706 fwSize = (pExtImage->ImageSize + 3) >> 2;
3707 ptrFw = (u32 *)pExtImage;
3709 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3710 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3711 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3713 while (fwSize--) {
3714 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3716 nextImage = pExtImage->NextImageHeaderOffset;
3719 /* Write the IopResetVectorRegAddr */
3720 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3721 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3723 /* Write the IopResetVectorValue */
3724 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3725 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3727 /* Clear the internal flash bad bit - autoincrementing register,
3728 * so must do two writes.
3730 if (ioc->bus_type == SPI) {
3732 * 1030 and 1035 H/W errata, workaround to access
3733 * the ClearFlashBadSignatureBit
3735 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3736 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3737 diagRwData |= 0x40000000;
3738 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3739 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3741 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3742 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3743 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3744 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3746 /* wait 1 msec */
3747 if (sleepFlag == CAN_SLEEP) {
3748 msleep (1);
3749 } else {
3750 mdelay (1);
3754 if (ioc->errata_flag_1064)
3755 pci_disable_io_access(ioc->pcidev);
3757 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3758 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3759 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3760 ioc->name, diag0val));
3761 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3762 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3763 ioc->name, diag0val));
3764 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3766 /* Write 0xFF to reset the sequencer */
3767 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3769 if (ioc->bus_type == SAS) {
3770 ioc_state = mpt_GetIocState(ioc, 0);
3771 if ( (GetIocFacts(ioc, sleepFlag,
3772 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3773 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3774 ioc->name, ioc_state));
3775 return -EFAULT;
3779 for (count=0; count<HZ*20; count++) {
3780 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3781 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3782 "downloadboot successful! (count=%d) IocState=%x\n",
3783 ioc->name, count, ioc_state));
3784 if (ioc->bus_type == SAS) {
3785 return 0;
3787 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3788 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3789 "downloadboot: SendIocInit failed\n",
3790 ioc->name));
3791 return -EFAULT;
3793 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3794 "downloadboot: SendIocInit successful\n",
3795 ioc->name));
3796 return 0;
3798 if (sleepFlag == CAN_SLEEP) {
3799 msleep (10);
3800 } else {
3801 mdelay (10);
3804 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3805 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3806 return -EFAULT;
3809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3811 * KickStart - Perform hard reset of MPT adapter.
3812 * @ioc: Pointer to MPT_ADAPTER structure
3813 * @force: Force hard reset
3814 * @sleepFlag: Specifies whether the process can sleep
3816 * This routine places MPT adapter in diagnostic mode via the
3817 * WriteSequence register, and then performs a hard reset of adapter
3818 * via the Diagnostic register.
3820 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3821 * or NO_SLEEP (interrupt thread, use mdelay)
3822 * force - 1 if doorbell active, board fault state
3823 * board operational, IOC_RECOVERY or
3824 * IOC_BRINGUP and there is an alt_ioc.
3825 * 0 else
3827 * Returns:
3828 * 1 - hard reset, READY
3829 * 0 - no reset due to History bit, READY
3830 * -1 - no reset due to History bit but not READY
3831 * OR reset but failed to come READY
3832 * -2 - no reset, could not enter DIAG mode
3833 * -3 - reset but bad FW bit
3835 static int
3836 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3838 int hard_reset_done = 0;
3839 u32 ioc_state=0;
3840 int cnt,cntdn;
3842 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3843 if (ioc->bus_type == SPI) {
3844 /* Always issue a Msg Unit Reset first. This will clear some
3845 * SCSI bus hang conditions.
3847 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3849 if (sleepFlag == CAN_SLEEP) {
3850 msleep (1000);
3851 } else {
3852 mdelay (1000);
3856 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3857 if (hard_reset_done < 0)
3858 return hard_reset_done;
3860 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3861 ioc->name));
3863 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3864 for (cnt=0; cnt<cntdn; cnt++) {
3865 ioc_state = mpt_GetIocState(ioc, 1);
3866 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3867 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3868 ioc->name, cnt));
3869 return hard_reset_done;
3871 if (sleepFlag == CAN_SLEEP) {
3872 msleep (10);
3873 } else {
3874 mdelay (10);
3878 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3879 ioc->name, mpt_GetIocState(ioc, 0)));
3880 return -1;
3883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3885 * mpt_diag_reset - Perform hard reset of the adapter.
3886 * @ioc: Pointer to MPT_ADAPTER structure
3887 * @ignore: Set if to honor and clear to ignore
3888 * the reset history bit
3889 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3890 * else set to NO_SLEEP (use mdelay instead)
3892 * This routine places the adapter in diagnostic mode via the
3893 * WriteSequence register and then performs a hard reset of adapter
3894 * via the Diagnostic register. Adapter should be in ready state
3895 * upon successful completion.
3897 * Returns: 1 hard reset successful
3898 * 0 no reset performed because reset history bit set
3899 * -2 enabling diagnostic mode failed
3900 * -3 diagnostic reset failed
3902 static int
3903 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3905 u32 diag0val;
3906 u32 doorbell;
3907 int hard_reset_done = 0;
3908 int count = 0;
3909 u32 diag1val = 0;
3910 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3911 u8 cb_idx;
3913 /* Clear any existing interrupts */
3914 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3916 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3918 if (!ignore)
3919 return 0;
3921 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3922 "address=%p\n", ioc->name, __func__,
3923 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3924 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3925 if (sleepFlag == CAN_SLEEP)
3926 msleep(1);
3927 else
3928 mdelay(1);
3931 * Call each currently registered protocol IOC reset handler
3932 * with pre-reset indication.
3933 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3934 * MptResetHandlers[] registered yet.
3936 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3937 if (MptResetHandlers[cb_idx])
3938 (*(MptResetHandlers[cb_idx]))(ioc,
3939 MPT_IOC_PRE_RESET);
3942 for (count = 0; count < 60; count ++) {
3943 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3944 doorbell &= MPI_IOC_STATE_MASK;
3946 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3947 "looking for READY STATE: doorbell=%x"
3948 " count=%d\n",
3949 ioc->name, doorbell, count));
3951 if (doorbell == MPI_IOC_STATE_READY) {
3952 return 1;
3955 /* wait 1 sec */
3956 if (sleepFlag == CAN_SLEEP)
3957 msleep(1000);
3958 else
3959 mdelay(1000);
3961 return -1;
3964 /* Use "Diagnostic reset" method! (only thing available!) */
3965 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3967 if (ioc->debug_level & MPT_DEBUG) {
3968 if (ioc->alt_ioc)
3969 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3970 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3971 ioc->name, diag0val, diag1val));
3974 /* Do the reset if we are told to ignore the reset history
3975 * or if the reset history is 0
3977 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3978 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3979 /* Write magic sequence to WriteSequence register
3980 * Loop until in diagnostic mode
3982 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3983 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3984 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3985 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3986 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3987 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3989 /* wait 100 msec */
3990 if (sleepFlag == CAN_SLEEP) {
3991 msleep (100);
3992 } else {
3993 mdelay (100);
3996 count++;
3997 if (count > 20) {
3998 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3999 ioc->name, diag0val);
4000 return -2;
4004 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4006 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4007 ioc->name, diag0val));
4010 if (ioc->debug_level & MPT_DEBUG) {
4011 if (ioc->alt_ioc)
4012 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4013 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4014 ioc->name, diag0val, diag1val));
4017 * Disable the ARM (Bug fix)
4020 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4021 mdelay(1);
4024 * Now hit the reset bit in the Diagnostic register
4025 * (THE BIG HAMMER!) (Clears DRWE bit).
4027 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4028 hard_reset_done = 1;
4029 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4030 ioc->name));
4033 * Call each currently registered protocol IOC reset handler
4034 * with pre-reset indication.
4035 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4036 * MptResetHandlers[] registered yet.
4038 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4039 if (MptResetHandlers[cb_idx]) {
4040 mpt_signal_reset(cb_idx,
4041 ioc, MPT_IOC_PRE_RESET);
4042 if (ioc->alt_ioc) {
4043 mpt_signal_reset(cb_idx,
4044 ioc->alt_ioc, MPT_IOC_PRE_RESET);
4049 if (ioc->cached_fw)
4050 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4051 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4052 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4053 else
4054 cached_fw = NULL;
4055 if (cached_fw) {
4056 /* If the DownloadBoot operation fails, the
4057 * IOC will be left unusable. This is a fatal error
4058 * case. _diag_reset will return < 0
4060 for (count = 0; count < 30; count ++) {
4061 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4062 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4063 break;
4066 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4067 ioc->name, diag0val, count));
4068 /* wait 1 sec */
4069 if (sleepFlag == CAN_SLEEP) {
4070 msleep (1000);
4071 } else {
4072 mdelay (1000);
4075 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4076 printk(MYIOC_s_WARN_FMT
4077 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4080 } else {
4081 /* Wait for FW to reload and for board
4082 * to go to the READY state.
4083 * Maximum wait is 60 seconds.
4084 * If fail, no error will check again
4085 * with calling program.
4087 for (count = 0; count < 60; count ++) {
4088 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4089 doorbell &= MPI_IOC_STATE_MASK;
4091 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4092 "looking for READY STATE: doorbell=%x"
4093 " count=%d\n", ioc->name, doorbell, count));
4095 if (doorbell == MPI_IOC_STATE_READY) {
4096 break;
4099 /* wait 1 sec */
4100 if (sleepFlag == CAN_SLEEP) {
4101 msleep (1000);
4102 } else {
4103 mdelay (1000);
4107 if (doorbell != MPI_IOC_STATE_READY)
4108 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4109 "after reset! IocState=%x", ioc->name,
4110 doorbell);
4114 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4115 if (ioc->debug_level & MPT_DEBUG) {
4116 if (ioc->alt_ioc)
4117 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4118 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4119 ioc->name, diag0val, diag1val));
4122 /* Clear RESET_HISTORY bit! Place board in the
4123 * diagnostic mode to update the diag register.
4125 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4126 count = 0;
4127 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4128 /* Write magic sequence to WriteSequence register
4129 * Loop until in diagnostic mode
4131 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4132 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4133 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4134 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4135 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4136 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4138 /* wait 100 msec */
4139 if (sleepFlag == CAN_SLEEP) {
4140 msleep (100);
4141 } else {
4142 mdelay (100);
4145 count++;
4146 if (count > 20) {
4147 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4148 ioc->name, diag0val);
4149 break;
4151 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4153 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4154 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4155 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4156 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4157 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4158 ioc->name);
4161 /* Disable Diagnostic Mode
4163 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4165 /* Check FW reload status flags.
4167 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4168 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4169 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4170 ioc->name, diag0val);
4171 return -3;
4174 if (ioc->debug_level & MPT_DEBUG) {
4175 if (ioc->alt_ioc)
4176 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4177 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4178 ioc->name, diag0val, diag1val));
4182 * Reset flag that says we've enabled event notification
4184 ioc->facts.EventState = 0;
4186 if (ioc->alt_ioc)
4187 ioc->alt_ioc->facts.EventState = 0;
4189 return hard_reset_done;
4192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4194 * SendIocReset - Send IOCReset request to MPT adapter.
4195 * @ioc: Pointer to MPT_ADAPTER structure
4196 * @reset_type: reset type, expected values are
4197 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4198 * @sleepFlag: Specifies whether the process can sleep
4200 * Send IOCReset request to the MPT adapter.
4202 * Returns 0 for success, non-zero for failure.
4204 static int
4205 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4207 int r;
4208 u32 state;
4209 int cntdn, count;
4211 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4212 ioc->name, reset_type));
4213 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4214 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4215 return r;
4217 /* FW ACK'd request, wait for READY state
4219 count = 0;
4220 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4222 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4223 cntdn--;
4224 count++;
4225 if (!cntdn) {
4226 if (sleepFlag != CAN_SLEEP)
4227 count *= 10;
4229 printk(MYIOC_s_ERR_FMT
4230 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4231 ioc->name, state, (int)((count+5)/HZ));
4232 return -ETIME;
4235 if (sleepFlag == CAN_SLEEP) {
4236 msleep(1);
4237 } else {
4238 mdelay (1); /* 1 msec delay */
4242 /* TODO!
4243 * Cleanup all event stuff for this IOC; re-issue EventNotification
4244 * request if needed.
4246 if (ioc->facts.Function)
4247 ioc->facts.EventState = 0;
4249 return 0;
4252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4254 * initChainBuffers - Allocate memory for and initialize chain buffers
4255 * @ioc: Pointer to MPT_ADAPTER structure
4257 * Allocates memory for and initializes chain buffers,
4258 * chain buffer control arrays and spinlock.
4260 static int
4261 initChainBuffers(MPT_ADAPTER *ioc)
4263 u8 *mem;
4264 int sz, ii, num_chain;
4265 int scale, num_sge, numSGE;
4267 /* ReqToChain size must equal the req_depth
4268 * index = req_idx
4270 if (ioc->ReqToChain == NULL) {
4271 sz = ioc->req_depth * sizeof(int);
4272 mem = kmalloc(sz, GFP_ATOMIC);
4273 if (mem == NULL)
4274 return -1;
4276 ioc->ReqToChain = (int *) mem;
4277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4278 ioc->name, mem, sz));
4279 mem = kmalloc(sz, GFP_ATOMIC);
4280 if (mem == NULL)
4281 return -1;
4283 ioc->RequestNB = (int *) mem;
4284 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4285 ioc->name, mem, sz));
4287 for (ii = 0; ii < ioc->req_depth; ii++) {
4288 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4291 /* ChainToChain size must equal the total number
4292 * of chain buffers to be allocated.
4293 * index = chain_idx
4295 * Calculate the number of chain buffers needed(plus 1) per I/O
4296 * then multiply the maximum number of simultaneous cmds
4298 * num_sge = num sge in request frame + last chain buffer
4299 * scale = num sge per chain buffer if no chain element
4301 scale = ioc->req_sz / ioc->SGE_size;
4302 if (ioc->sg_addr_size == sizeof(u64))
4303 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4304 else
4305 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4307 if (ioc->sg_addr_size == sizeof(u64)) {
4308 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4309 (ioc->req_sz - 60) / ioc->SGE_size;
4310 } else {
4311 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4312 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4314 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4315 ioc->name, num_sge, numSGE));
4317 if (ioc->bus_type == FC) {
4318 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4319 numSGE = MPT_SCSI_FC_SG_DEPTH;
4320 } else {
4321 if (numSGE > MPT_SCSI_SG_DEPTH)
4322 numSGE = MPT_SCSI_SG_DEPTH;
4325 num_chain = 1;
4326 while (numSGE - num_sge > 0) {
4327 num_chain++;
4328 num_sge += (scale - 1);
4330 num_chain++;
4332 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4333 ioc->name, numSGE, num_sge, num_chain));
4335 if (ioc->bus_type == SPI)
4336 num_chain *= MPT_SCSI_CAN_QUEUE;
4337 else if (ioc->bus_type == SAS)
4338 num_chain *= MPT_SAS_CAN_QUEUE;
4339 else
4340 num_chain *= MPT_FC_CAN_QUEUE;
4342 ioc->num_chain = num_chain;
4344 sz = num_chain * sizeof(int);
4345 if (ioc->ChainToChain == NULL) {
4346 mem = kmalloc(sz, GFP_ATOMIC);
4347 if (mem == NULL)
4348 return -1;
4350 ioc->ChainToChain = (int *) mem;
4351 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4352 ioc->name, mem, sz));
4353 } else {
4354 mem = (u8 *) ioc->ChainToChain;
4356 memset(mem, 0xFF, sz);
4357 return num_chain;
4360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4362 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4363 * @ioc: Pointer to MPT_ADAPTER structure
4365 * This routine allocates memory for the MPT reply and request frame
4366 * pools (if necessary), and primes the IOC reply FIFO with
4367 * reply frames.
4369 * Returns 0 for success, non-zero for failure.
4371 static int
4372 PrimeIocFifos(MPT_ADAPTER *ioc)
4374 MPT_FRAME_HDR *mf;
4375 unsigned long flags;
4376 dma_addr_t alloc_dma;
4377 u8 *mem;
4378 int i, reply_sz, sz, total_size, num_chain;
4379 u64 dma_mask;
4381 dma_mask = 0;
4383 /* Prime reply FIFO... */
4385 if (ioc->reply_frames == NULL) {
4386 if ( (num_chain = initChainBuffers(ioc)) < 0)
4387 return -1;
4389 * 1078 errata workaround for the 36GB limitation
4391 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4392 ioc->dma_mask > DMA_BIT_MASK(35)) {
4393 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4394 && !pci_set_consistent_dma_mask(ioc->pcidev,
4395 DMA_BIT_MASK(32))) {
4396 dma_mask = DMA_BIT_MASK(35);
4397 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4398 "setting 35 bit addressing for "
4399 "Request/Reply/Chain and Sense Buffers\n",
4400 ioc->name));
4401 } else {
4402 /*Reseting DMA mask to 64 bit*/
4403 pci_set_dma_mask(ioc->pcidev,
4404 DMA_BIT_MASK(64));
4405 pci_set_consistent_dma_mask(ioc->pcidev,
4406 DMA_BIT_MASK(64));
4408 printk(MYIOC_s_ERR_FMT
4409 "failed setting 35 bit addressing for "
4410 "Request/Reply/Chain and Sense Buffers\n",
4411 ioc->name);
4412 return -1;
4416 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4417 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4418 ioc->name, ioc->reply_sz, ioc->reply_depth));
4419 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4420 ioc->name, reply_sz, reply_sz));
4422 sz = (ioc->req_sz * ioc->req_depth);
4423 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4424 ioc->name, ioc->req_sz, ioc->req_depth));
4425 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4426 ioc->name, sz, sz));
4427 total_size += sz;
4429 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4430 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4431 ioc->name, ioc->req_sz, num_chain));
4432 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4433 ioc->name, sz, sz, num_chain));
4435 total_size += sz;
4436 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4437 if (mem == NULL) {
4438 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4439 ioc->name);
4440 goto out_fail;
4443 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4444 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4446 memset(mem, 0, total_size);
4447 ioc->alloc_total += total_size;
4448 ioc->alloc = mem;
4449 ioc->alloc_dma = alloc_dma;
4450 ioc->alloc_sz = total_size;
4451 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4452 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4454 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4455 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4457 alloc_dma += reply_sz;
4458 mem += reply_sz;
4460 /* Request FIFO - WE manage this! */
4462 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4463 ioc->req_frames_dma = alloc_dma;
4465 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4466 ioc->name, mem, (void *)(ulong)alloc_dma));
4468 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4470 #if defined(CONFIG_MTRR) && 0
4472 * Enable Write Combining MTRR for IOC's memory region.
4473 * (at least as much as we can; "size and base must be
4474 * multiples of 4 kiB"
4476 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4478 MTRR_TYPE_WRCOMB, 1);
4479 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4480 ioc->name, ioc->req_frames_dma, sz));
4481 #endif
4483 for (i = 0; i < ioc->req_depth; i++) {
4484 alloc_dma += ioc->req_sz;
4485 mem += ioc->req_sz;
4488 ioc->ChainBuffer = mem;
4489 ioc->ChainBufferDMA = alloc_dma;
4491 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4492 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4494 /* Initialize the free chain Q.
4497 INIT_LIST_HEAD(&ioc->FreeChainQ);
4499 /* Post the chain buffers to the FreeChainQ.
4501 mem = (u8 *)ioc->ChainBuffer;
4502 for (i=0; i < num_chain; i++) {
4503 mf = (MPT_FRAME_HDR *) mem;
4504 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4505 mem += ioc->req_sz;
4508 /* Initialize Request frames linked list
4510 alloc_dma = ioc->req_frames_dma;
4511 mem = (u8 *) ioc->req_frames;
4513 spin_lock_irqsave(&ioc->FreeQlock, flags);
4514 INIT_LIST_HEAD(&ioc->FreeQ);
4515 for (i = 0; i < ioc->req_depth; i++) {
4516 mf = (MPT_FRAME_HDR *) mem;
4518 /* Queue REQUESTs *internally*! */
4519 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4521 mem += ioc->req_sz;
4523 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4525 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4526 ioc->sense_buf_pool =
4527 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4528 if (ioc->sense_buf_pool == NULL) {
4529 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4530 ioc->name);
4531 goto out_fail;
4534 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4535 ioc->alloc_total += sz;
4536 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4537 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4541 /* Post Reply frames to FIFO
4543 alloc_dma = ioc->alloc_dma;
4544 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4545 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4547 for (i = 0; i < ioc->reply_depth; i++) {
4548 /* Write each address to the IOC! */
4549 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4550 alloc_dma += ioc->reply_sz;
4553 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4554 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4555 ioc->dma_mask))
4556 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4557 "restoring 64 bit addressing\n", ioc->name));
4559 return 0;
4561 out_fail:
4563 if (ioc->alloc != NULL) {
4564 sz = ioc->alloc_sz;
4565 pci_free_consistent(ioc->pcidev,
4567 ioc->alloc, ioc->alloc_dma);
4568 ioc->reply_frames = NULL;
4569 ioc->req_frames = NULL;
4570 ioc->alloc_total -= sz;
4572 if (ioc->sense_buf_pool != NULL) {
4573 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4574 pci_free_consistent(ioc->pcidev,
4576 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4577 ioc->sense_buf_pool = NULL;
4580 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4581 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4582 DMA_BIT_MASK(64)))
4583 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4584 "restoring 64 bit addressing\n", ioc->name));
4586 return -1;
4589 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4591 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4592 * from IOC via doorbell handshake method.
4593 * @ioc: Pointer to MPT_ADAPTER structure
4594 * @reqBytes: Size of the request in bytes
4595 * @req: Pointer to MPT request frame
4596 * @replyBytes: Expected size of the reply in bytes
4597 * @u16reply: Pointer to area where reply should be written
4598 * @maxwait: Max wait time for a reply (in seconds)
4599 * @sleepFlag: Specifies whether the process can sleep
4601 * NOTES: It is the callers responsibility to byte-swap fields in the
4602 * request which are greater than 1 byte in size. It is also the
4603 * callers responsibility to byte-swap response fields which are
4604 * greater than 1 byte in size.
4606 * Returns 0 for success, non-zero for failure.
4608 static int
4609 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4610 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4612 MPIDefaultReply_t *mptReply;
4613 int failcnt = 0;
4614 int t;
4617 * Get ready to cache a handshake reply
4619 ioc->hs_reply_idx = 0;
4620 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4621 mptReply->MsgLength = 0;
4624 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4625 * then tell IOC that we want to handshake a request of N words.
4626 * (WRITE u32val to Doorbell reg).
4628 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4629 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4630 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4631 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4634 * Wait for IOC's doorbell handshake int
4636 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4637 failcnt++;
4639 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4640 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4642 /* Read doorbell and check for active bit */
4643 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4644 return -1;
4647 * Clear doorbell int (WRITE 0 to IntStatus reg),
4648 * then wait for IOC to ACKnowledge that it's ready for
4649 * our handshake request.
4651 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4652 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4653 failcnt++;
4655 if (!failcnt) {
4656 int ii;
4657 u8 *req_as_bytes = (u8 *) req;
4660 * Stuff request words via doorbell handshake,
4661 * with ACK from IOC for each.
4663 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4664 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4665 (req_as_bytes[(ii*4) + 1] << 8) |
4666 (req_as_bytes[(ii*4) + 2] << 16) |
4667 (req_as_bytes[(ii*4) + 3] << 24));
4669 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4670 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4671 failcnt++;
4674 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4675 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4677 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4678 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4681 * Wait for completion of doorbell handshake reply from the IOC
4683 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4684 failcnt++;
4686 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4687 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4690 * Copy out the cached reply...
4692 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4693 u16reply[ii] = ioc->hs_reply[ii];
4694 } else {
4695 return -99;
4698 return -failcnt;
4701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4703 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4704 * @ioc: Pointer to MPT_ADAPTER structure
4705 * @howlong: How long to wait (in seconds)
4706 * @sleepFlag: Specifies whether the process can sleep
4708 * This routine waits (up to ~2 seconds max) for IOC doorbell
4709 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4710 * bit in its IntStatus register being clear.
4712 * Returns a negative value on failure, else wait loop count.
4714 static int
4715 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4717 int cntdn;
4718 int count = 0;
4719 u32 intstat=0;
4721 cntdn = 1000 * howlong;
4723 if (sleepFlag == CAN_SLEEP) {
4724 while (--cntdn) {
4725 msleep (1);
4726 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4727 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4728 break;
4729 count++;
4731 } else {
4732 while (--cntdn) {
4733 udelay (1000);
4734 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4735 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4736 break;
4737 count++;
4741 if (cntdn) {
4742 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4743 ioc->name, count));
4744 return count;
4747 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4748 ioc->name, count, intstat);
4749 return -1;
4752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4754 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4755 * @ioc: Pointer to MPT_ADAPTER structure
4756 * @howlong: How long to wait (in seconds)
4757 * @sleepFlag: Specifies whether the process can sleep
4759 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4760 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4762 * Returns a negative value on failure, else wait loop count.
4764 static int
4765 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4767 int cntdn;
4768 int count = 0;
4769 u32 intstat=0;
4771 cntdn = 1000 * howlong;
4772 if (sleepFlag == CAN_SLEEP) {
4773 while (--cntdn) {
4774 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4775 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4776 break;
4777 msleep(1);
4778 count++;
4780 } else {
4781 while (--cntdn) {
4782 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4783 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4784 break;
4785 udelay (1000);
4786 count++;
4790 if (cntdn) {
4791 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4792 ioc->name, count, howlong));
4793 return count;
4796 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4797 ioc->name, count, intstat);
4798 return -1;
4801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4803 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4804 * @ioc: Pointer to MPT_ADAPTER structure
4805 * @howlong: How long to wait (in seconds)
4806 * @sleepFlag: Specifies whether the process can sleep
4808 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4809 * Reply is cached to IOC private area large enough to hold a maximum
4810 * of 128 bytes of reply data.
4812 * Returns a negative value on failure, else size of reply in WORDS.
4814 static int
4815 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4817 int u16cnt = 0;
4818 int failcnt = 0;
4819 int t;
4820 u16 *hs_reply = ioc->hs_reply;
4821 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4822 u16 hword;
4824 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4827 * Get first two u16's so we can look at IOC's intended reply MsgLength
4829 u16cnt=0;
4830 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4831 failcnt++;
4832 } else {
4833 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4834 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4835 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4836 failcnt++;
4837 else {
4838 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4839 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4843 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4844 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4845 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4848 * If no error (and IOC said MsgLength is > 0), piece together
4849 * reply 16 bits at a time.
4851 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4852 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4853 failcnt++;
4854 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4855 /* don't overflow our IOC hs_reply[] buffer! */
4856 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4857 hs_reply[u16cnt] = hword;
4858 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4861 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4862 failcnt++;
4863 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4865 if (failcnt) {
4866 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4867 ioc->name);
4868 return -failcnt;
4870 #if 0
4871 else if (u16cnt != (2 * mptReply->MsgLength)) {
4872 return -101;
4874 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4875 return -102;
4877 #endif
4879 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4880 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4882 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4883 ioc->name, t, u16cnt/2));
4884 return u16cnt/2;
4887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4889 * GetLanConfigPages - Fetch LANConfig pages.
4890 * @ioc: Pointer to MPT_ADAPTER structure
4892 * Return: 0 for success
4893 * -ENOMEM if no memory available
4894 * -EPERM if not allowed due to ISR context
4895 * -EAGAIN if no msg frames currently available
4896 * -EFAULT for non-successful reply or no reply (timeout)
4898 static int
4899 GetLanConfigPages(MPT_ADAPTER *ioc)
4901 ConfigPageHeader_t hdr;
4902 CONFIGPARMS cfg;
4903 LANPage0_t *ppage0_alloc;
4904 dma_addr_t page0_dma;
4905 LANPage1_t *ppage1_alloc;
4906 dma_addr_t page1_dma;
4907 int rc = 0;
4908 int data_sz;
4909 int copy_sz;
4911 /* Get LAN Page 0 header */
4912 hdr.PageVersion = 0;
4913 hdr.PageLength = 0;
4914 hdr.PageNumber = 0;
4915 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4916 cfg.cfghdr.hdr = &hdr;
4917 cfg.physAddr = -1;
4918 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4919 cfg.dir = 0;
4920 cfg.pageAddr = 0;
4921 cfg.timeout = 0;
4923 if ((rc = mpt_config(ioc, &cfg)) != 0)
4924 return rc;
4926 if (hdr.PageLength > 0) {
4927 data_sz = hdr.PageLength * 4;
4928 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4929 rc = -ENOMEM;
4930 if (ppage0_alloc) {
4931 memset((u8 *)ppage0_alloc, 0, data_sz);
4932 cfg.physAddr = page0_dma;
4933 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4935 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4936 /* save the data */
4937 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4938 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4942 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4944 /* FIXME!
4945 * Normalize endianness of structure data,
4946 * by byte-swapping all > 1 byte fields!
4951 if (rc)
4952 return rc;
4955 /* Get LAN Page 1 header */
4956 hdr.PageVersion = 0;
4957 hdr.PageLength = 0;
4958 hdr.PageNumber = 1;
4959 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4960 cfg.cfghdr.hdr = &hdr;
4961 cfg.physAddr = -1;
4962 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4963 cfg.dir = 0;
4964 cfg.pageAddr = 0;
4966 if ((rc = mpt_config(ioc, &cfg)) != 0)
4967 return rc;
4969 if (hdr.PageLength == 0)
4970 return 0;
4972 data_sz = hdr.PageLength * 4;
4973 rc = -ENOMEM;
4974 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4975 if (ppage1_alloc) {
4976 memset((u8 *)ppage1_alloc, 0, data_sz);
4977 cfg.physAddr = page1_dma;
4978 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4980 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4981 /* save the data */
4982 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4983 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4986 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4988 /* FIXME!
4989 * Normalize endianness of structure data,
4990 * by byte-swapping all > 1 byte fields!
4995 return rc;
4998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5000 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5001 * @ioc: Pointer to MPT_ADAPTER structure
5002 * @persist_opcode: see below
5004 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5005 * devices not currently present.
5006 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5008 * NOTE: Don't use not this function during interrupt time.
5010 * Returns 0 for success, non-zero error
5013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5015 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5017 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5018 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5019 MPT_FRAME_HDR *mf = NULL;
5020 MPIHeader_t *mpi_hdr;
5021 int ret = 0;
5022 unsigned long timeleft;
5024 mutex_lock(&ioc->mptbase_cmds.mutex);
5026 /* init the internal cmd struct */
5027 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5028 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5030 /* insure garbage is not sent to fw */
5031 switch(persist_opcode) {
5033 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5034 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5035 break;
5037 default:
5038 ret = -1;
5039 goto out;
5042 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5043 __func__, persist_opcode);
5045 /* Get a MF for this command.
5047 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5048 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5049 ret = -1;
5050 goto out;
5053 mpi_hdr = (MPIHeader_t *) mf;
5054 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5055 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5056 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5057 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5058 sasIoUnitCntrReq->Operation = persist_opcode;
5060 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5061 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5062 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5063 ret = -ETIME;
5064 printk(KERN_DEBUG "%s: failed\n", __func__);
5065 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5066 goto out;
5067 if (!timeleft) {
5068 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
5069 ioc->name, __func__);
5070 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5071 mpt_free_msg_frame(ioc, mf);
5073 goto out;
5076 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5077 ret = -1;
5078 goto out;
5081 sasIoUnitCntrReply =
5082 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5083 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5084 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5085 __func__, sasIoUnitCntrReply->IOCStatus,
5086 sasIoUnitCntrReply->IOCLogInfo);
5087 printk(KERN_DEBUG "%s: failed\n", __func__);
5088 ret = -1;
5089 } else
5090 printk(KERN_DEBUG "%s: success\n", __func__);
5091 out:
5093 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5094 mutex_unlock(&ioc->mptbase_cmds.mutex);
5095 return ret;
5098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5100 static void
5101 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5102 MpiEventDataRaid_t * pRaidEventData)
5104 int volume;
5105 int reason;
5106 int disk;
5107 int status;
5108 int flags;
5109 int state;
5111 volume = pRaidEventData->VolumeID;
5112 reason = pRaidEventData->ReasonCode;
5113 disk = pRaidEventData->PhysDiskNum;
5114 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5115 flags = (status >> 0) & 0xff;
5116 state = (status >> 8) & 0xff;
5118 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5119 return;
5122 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5123 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5124 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5125 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5126 ioc->name, disk, volume);
5127 } else {
5128 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5129 ioc->name, volume);
5132 switch(reason) {
5133 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5134 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5135 ioc->name);
5136 break;
5138 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5140 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5141 ioc->name);
5142 break;
5144 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5145 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5146 ioc->name);
5147 break;
5149 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5150 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5151 ioc->name,
5152 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5153 ? "optimal"
5154 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5155 ? "degraded"
5156 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5157 ? "failed"
5158 : "state unknown",
5159 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5160 ? ", enabled" : "",
5161 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5162 ? ", quiesced" : "",
5163 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5164 ? ", resync in progress" : "" );
5165 break;
5167 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5168 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5169 ioc->name, disk);
5170 break;
5172 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5173 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5174 ioc->name);
5175 break;
5177 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5178 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5179 ioc->name);
5180 break;
5182 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5183 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5184 ioc->name);
5185 break;
5187 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5188 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5189 ioc->name,
5190 state == MPI_PHYSDISK0_STATUS_ONLINE
5191 ? "online"
5192 : state == MPI_PHYSDISK0_STATUS_MISSING
5193 ? "missing"
5194 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5195 ? "not compatible"
5196 : state == MPI_PHYSDISK0_STATUS_FAILED
5197 ? "failed"
5198 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5199 ? "initializing"
5200 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5201 ? "offline requested"
5202 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5203 ? "failed requested"
5204 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5205 ? "offline"
5206 : "state unknown",
5207 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5208 ? ", out of sync" : "",
5209 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5210 ? ", quiesced" : "" );
5211 break;
5213 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5214 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5215 ioc->name, disk);
5216 break;
5218 case MPI_EVENT_RAID_RC_SMART_DATA:
5219 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5220 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5221 break;
5223 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5224 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5225 ioc->name, disk);
5226 break;
5230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5232 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5233 * @ioc: Pointer to MPT_ADAPTER structure
5235 * Returns: 0 for success
5236 * -ENOMEM if no memory available
5237 * -EPERM if not allowed due to ISR context
5238 * -EAGAIN if no msg frames currently available
5239 * -EFAULT for non-successful reply or no reply (timeout)
5241 static int
5242 GetIoUnitPage2(MPT_ADAPTER *ioc)
5244 ConfigPageHeader_t hdr;
5245 CONFIGPARMS cfg;
5246 IOUnitPage2_t *ppage_alloc;
5247 dma_addr_t page_dma;
5248 int data_sz;
5249 int rc;
5251 /* Get the page header */
5252 hdr.PageVersion = 0;
5253 hdr.PageLength = 0;
5254 hdr.PageNumber = 2;
5255 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5256 cfg.cfghdr.hdr = &hdr;
5257 cfg.physAddr = -1;
5258 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5259 cfg.dir = 0;
5260 cfg.pageAddr = 0;
5261 cfg.timeout = 0;
5263 if ((rc = mpt_config(ioc, &cfg)) != 0)
5264 return rc;
5266 if (hdr.PageLength == 0)
5267 return 0;
5269 /* Read the config page */
5270 data_sz = hdr.PageLength * 4;
5271 rc = -ENOMEM;
5272 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5273 if (ppage_alloc) {
5274 memset((u8 *)ppage_alloc, 0, data_sz);
5275 cfg.physAddr = page_dma;
5276 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5278 /* If Good, save data */
5279 if ((rc = mpt_config(ioc, &cfg)) == 0)
5280 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5282 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5285 return rc;
5288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5290 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5291 * @ioc: Pointer to a Adapter Strucutre
5292 * @portnum: IOC port number
5294 * Return: -EFAULT if read of config page header fails
5295 * or if no nvram
5296 * If read of SCSI Port Page 0 fails,
5297 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5298 * Adapter settings: async, narrow
5299 * Return 1
5300 * If read of SCSI Port Page 2 fails,
5301 * Adapter settings valid
5302 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5303 * Return 1
5304 * Else
5305 * Both valid
5306 * Return 0
5307 * CHECK - what type of locking mechanisms should be used????
5309 static int
5310 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5312 u8 *pbuf;
5313 dma_addr_t buf_dma;
5314 CONFIGPARMS cfg;
5315 ConfigPageHeader_t header;
5316 int ii;
5317 int data, rc = 0;
5319 /* Allocate memory
5321 if (!ioc->spi_data.nvram) {
5322 int sz;
5323 u8 *mem;
5324 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5325 mem = kmalloc(sz, GFP_ATOMIC);
5326 if (mem == NULL)
5327 return -EFAULT;
5329 ioc->spi_data.nvram = (int *) mem;
5331 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5332 ioc->name, ioc->spi_data.nvram, sz));
5335 /* Invalidate NVRAM information
5337 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5338 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5341 /* Read SPP0 header, allocate memory, then read page.
5343 header.PageVersion = 0;
5344 header.PageLength = 0;
5345 header.PageNumber = 0;
5346 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5347 cfg.cfghdr.hdr = &header;
5348 cfg.physAddr = -1;
5349 cfg.pageAddr = portnum;
5350 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5351 cfg.dir = 0;
5352 cfg.timeout = 0; /* use default */
5353 if (mpt_config(ioc, &cfg) != 0)
5354 return -EFAULT;
5356 if (header.PageLength > 0) {
5357 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5358 if (pbuf) {
5359 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5360 cfg.physAddr = buf_dma;
5361 if (mpt_config(ioc, &cfg) != 0) {
5362 ioc->spi_data.maxBusWidth = MPT_NARROW;
5363 ioc->spi_data.maxSyncOffset = 0;
5364 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5365 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5366 rc = 1;
5367 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5368 "Unable to read PortPage0 minSyncFactor=%x\n",
5369 ioc->name, ioc->spi_data.minSyncFactor));
5370 } else {
5371 /* Save the Port Page 0 data
5373 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5374 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5375 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5377 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5378 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5379 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5380 "noQas due to Capabilities=%x\n",
5381 ioc->name, pPP0->Capabilities));
5383 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5384 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5385 if (data) {
5386 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5387 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5388 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5389 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5390 "PortPage0 minSyncFactor=%x\n",
5391 ioc->name, ioc->spi_data.minSyncFactor));
5392 } else {
5393 ioc->spi_data.maxSyncOffset = 0;
5394 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5397 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5399 /* Update the minSyncFactor based on bus type.
5401 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5402 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5404 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5405 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5406 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5407 "HVD or SE detected, minSyncFactor=%x\n",
5408 ioc->name, ioc->spi_data.minSyncFactor));
5412 if (pbuf) {
5413 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5418 /* SCSI Port Page 2 - Read the header then the page.
5420 header.PageVersion = 0;
5421 header.PageLength = 0;
5422 header.PageNumber = 2;
5423 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5424 cfg.cfghdr.hdr = &header;
5425 cfg.physAddr = -1;
5426 cfg.pageAddr = portnum;
5427 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5428 cfg.dir = 0;
5429 if (mpt_config(ioc, &cfg) != 0)
5430 return -EFAULT;
5432 if (header.PageLength > 0) {
5433 /* Allocate memory and read SCSI Port Page 2
5435 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5436 if (pbuf) {
5437 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5438 cfg.physAddr = buf_dma;
5439 if (mpt_config(ioc, &cfg) != 0) {
5440 /* Nvram data is left with INVALID mark
5442 rc = 1;
5443 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5445 /* This is an ATTO adapter, read Page2 accordingly
5447 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5448 ATTODeviceInfo_t *pdevice = NULL;
5449 u16 ATTOFlags;
5451 /* Save the Port Page 2 data
5452 * (reformat into a 32bit quantity)
5454 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5455 pdevice = &pPP2->DeviceSettings[ii];
5456 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5457 data = 0;
5459 /* Translate ATTO device flags to LSI format
5461 if (ATTOFlags & ATTOFLAG_DISC)
5462 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5463 if (ATTOFlags & ATTOFLAG_ID_ENB)
5464 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5465 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5466 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5467 if (ATTOFlags & ATTOFLAG_TAGGED)
5468 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5469 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5470 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5472 data = (data << 16) | (pdevice->Period << 8) | 10;
5473 ioc->spi_data.nvram[ii] = data;
5475 } else {
5476 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5477 MpiDeviceInfo_t *pdevice = NULL;
5480 * Save "Set to Avoid SCSI Bus Resets" flag
5482 ioc->spi_data.bus_reset =
5483 (le32_to_cpu(pPP2->PortFlags) &
5484 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5485 0 : 1 ;
5487 /* Save the Port Page 2 data
5488 * (reformat into a 32bit quantity)
5490 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5491 ioc->spi_data.PortFlags = data;
5492 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5493 pdevice = &pPP2->DeviceSettings[ii];
5494 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5495 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5496 ioc->spi_data.nvram[ii] = data;
5500 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5504 /* Update Adapter limits with those from NVRAM
5505 * Comment: Don't need to do this. Target performance
5506 * parameters will never exceed the adapters limits.
5509 return rc;
5512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5514 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5515 * @ioc: Pointer to a Adapter Strucutre
5516 * @portnum: IOC port number
5518 * Return: -EFAULT if read of config page header fails
5519 * or 0 if success.
5521 static int
5522 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5524 CONFIGPARMS cfg;
5525 ConfigPageHeader_t header;
5527 /* Read the SCSI Device Page 1 header
5529 header.PageVersion = 0;
5530 header.PageLength = 0;
5531 header.PageNumber = 1;
5532 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5533 cfg.cfghdr.hdr = &header;
5534 cfg.physAddr = -1;
5535 cfg.pageAddr = portnum;
5536 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5537 cfg.dir = 0;
5538 cfg.timeout = 0;
5539 if (mpt_config(ioc, &cfg) != 0)
5540 return -EFAULT;
5542 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5543 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5545 header.PageVersion = 0;
5546 header.PageLength = 0;
5547 header.PageNumber = 0;
5548 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5549 if (mpt_config(ioc, &cfg) != 0)
5550 return -EFAULT;
5552 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5553 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5555 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5556 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5558 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5559 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5560 return 0;
5564 * mpt_inactive_raid_list_free - This clears this link list.
5565 * @ioc : pointer to per adapter structure
5567 static void
5568 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5570 struct inactive_raid_component_info *component_info, *pNext;
5572 if (list_empty(&ioc->raid_data.inactive_list))
5573 return;
5575 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5576 list_for_each_entry_safe(component_info, pNext,
5577 &ioc->raid_data.inactive_list, list) {
5578 list_del(&component_info->list);
5579 kfree(component_info);
5581 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5585 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5587 * @ioc : pointer to per adapter structure
5588 * @channel : volume channel
5589 * @id : volume target id
5591 static void
5592 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5594 CONFIGPARMS cfg;
5595 ConfigPageHeader_t hdr;
5596 dma_addr_t dma_handle;
5597 pRaidVolumePage0_t buffer = NULL;
5598 int i;
5599 RaidPhysDiskPage0_t phys_disk;
5600 struct inactive_raid_component_info *component_info;
5601 int handle_inactive_volumes;
5603 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5604 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5605 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5606 cfg.pageAddr = (channel << 8) + id;
5607 cfg.cfghdr.hdr = &hdr;
5608 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5610 if (mpt_config(ioc, &cfg) != 0)
5611 goto out;
5613 if (!hdr.PageLength)
5614 goto out;
5616 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5617 &dma_handle);
5619 if (!buffer)
5620 goto out;
5622 cfg.physAddr = dma_handle;
5623 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5625 if (mpt_config(ioc, &cfg) != 0)
5626 goto out;
5628 if (!buffer->NumPhysDisks)
5629 goto out;
5631 handle_inactive_volumes =
5632 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5633 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5634 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5635 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5637 if (!handle_inactive_volumes)
5638 goto out;
5640 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5641 for (i = 0; i < buffer->NumPhysDisks; i++) {
5642 if(mpt_raid_phys_disk_pg0(ioc,
5643 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5644 continue;
5646 if ((component_info = kmalloc(sizeof (*component_info),
5647 GFP_KERNEL)) == NULL)
5648 continue;
5650 component_info->volumeID = id;
5651 component_info->volumeBus = channel;
5652 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5653 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5654 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5655 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5657 list_add_tail(&component_info->list,
5658 &ioc->raid_data.inactive_list);
5660 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5662 out:
5663 if (buffer)
5664 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5665 dma_handle);
5669 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5670 * @ioc: Pointer to a Adapter Structure
5671 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5672 * @phys_disk: requested payload data returned
5674 * Return:
5675 * 0 on success
5676 * -EFAULT if read of config page header fails or data pointer not NULL
5677 * -ENOMEM if pci_alloc failed
5680 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5681 RaidPhysDiskPage0_t *phys_disk)
5683 CONFIGPARMS cfg;
5684 ConfigPageHeader_t hdr;
5685 dma_addr_t dma_handle;
5686 pRaidPhysDiskPage0_t buffer = NULL;
5687 int rc;
5689 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5690 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5691 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5693 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5694 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5695 cfg.cfghdr.hdr = &hdr;
5696 cfg.physAddr = -1;
5697 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5699 if (mpt_config(ioc, &cfg) != 0) {
5700 rc = -EFAULT;
5701 goto out;
5704 if (!hdr.PageLength) {
5705 rc = -EFAULT;
5706 goto out;
5709 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5710 &dma_handle);
5712 if (!buffer) {
5713 rc = -ENOMEM;
5714 goto out;
5717 cfg.physAddr = dma_handle;
5718 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5719 cfg.pageAddr = phys_disk_num;
5721 if (mpt_config(ioc, &cfg) != 0) {
5722 rc = -EFAULT;
5723 goto out;
5726 rc = 0;
5727 memcpy(phys_disk, buffer, sizeof(*buffer));
5728 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5730 out:
5732 if (buffer)
5733 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5734 dma_handle);
5736 return rc;
5740 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5741 * @ioc: Pointer to a Adapter Structure
5742 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5744 * Return:
5745 * returns number paths
5748 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5750 CONFIGPARMS cfg;
5751 ConfigPageHeader_t hdr;
5752 dma_addr_t dma_handle;
5753 pRaidPhysDiskPage1_t buffer = NULL;
5754 int rc;
5756 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5757 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5759 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5760 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5761 hdr.PageNumber = 1;
5762 cfg.cfghdr.hdr = &hdr;
5763 cfg.physAddr = -1;
5764 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5766 if (mpt_config(ioc, &cfg) != 0) {
5767 rc = 0;
5768 goto out;
5771 if (!hdr.PageLength) {
5772 rc = 0;
5773 goto out;
5776 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5777 &dma_handle);
5779 if (!buffer) {
5780 rc = 0;
5781 goto out;
5784 cfg.physAddr = dma_handle;
5785 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5786 cfg.pageAddr = phys_disk_num;
5788 if (mpt_config(ioc, &cfg) != 0) {
5789 rc = 0;
5790 goto out;
5793 rc = buffer->NumPhysDiskPaths;
5794 out:
5796 if (buffer)
5797 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5798 dma_handle);
5800 return rc;
5802 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5805 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5806 * @ioc: Pointer to a Adapter Structure
5807 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5808 * @phys_disk: requested payload data returned
5810 * Return:
5811 * 0 on success
5812 * -EFAULT if read of config page header fails or data pointer not NULL
5813 * -ENOMEM if pci_alloc failed
5816 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5817 RaidPhysDiskPage1_t *phys_disk)
5819 CONFIGPARMS cfg;
5820 ConfigPageHeader_t hdr;
5821 dma_addr_t dma_handle;
5822 pRaidPhysDiskPage1_t buffer = NULL;
5823 int rc;
5824 int i;
5825 __le64 sas_address;
5827 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5828 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5829 rc = 0;
5831 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5832 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5833 hdr.PageNumber = 1;
5834 cfg.cfghdr.hdr = &hdr;
5835 cfg.physAddr = -1;
5836 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5838 if (mpt_config(ioc, &cfg) != 0) {
5839 rc = -EFAULT;
5840 goto out;
5843 if (!hdr.PageLength) {
5844 rc = -EFAULT;
5845 goto out;
5848 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5849 &dma_handle);
5851 if (!buffer) {
5852 rc = -ENOMEM;
5853 goto out;
5856 cfg.physAddr = dma_handle;
5857 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5858 cfg.pageAddr = phys_disk_num;
5860 if (mpt_config(ioc, &cfg) != 0) {
5861 rc = -EFAULT;
5862 goto out;
5865 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5866 phys_disk->PhysDiskNum = phys_disk_num;
5867 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5868 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5869 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5870 phys_disk->Path[i].OwnerIdentifier =
5871 buffer->Path[i].OwnerIdentifier;
5872 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5873 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5874 sas_address = le64_to_cpu(sas_address);
5875 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5876 memcpy(&sas_address,
5877 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5878 sas_address = le64_to_cpu(sas_address);
5879 memcpy(&phys_disk->Path[i].OwnerWWID,
5880 &sas_address, sizeof(__le64));
5883 out:
5885 if (buffer)
5886 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5887 dma_handle);
5889 return rc;
5891 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5895 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5896 * @ioc: Pointer to a Adapter Strucutre
5898 * Return:
5899 * 0 on success
5900 * -EFAULT if read of config page header fails or data pointer not NULL
5901 * -ENOMEM if pci_alloc failed
5904 mpt_findImVolumes(MPT_ADAPTER *ioc)
5906 IOCPage2_t *pIoc2;
5907 u8 *mem;
5908 dma_addr_t ioc2_dma;
5909 CONFIGPARMS cfg;
5910 ConfigPageHeader_t header;
5911 int rc = 0;
5912 int iocpage2sz;
5913 int i;
5915 if (!ioc->ir_firmware)
5916 return 0;
5918 /* Free the old page
5920 kfree(ioc->raid_data.pIocPg2);
5921 ioc->raid_data.pIocPg2 = NULL;
5922 mpt_inactive_raid_list_free(ioc);
5924 /* Read IOCP2 header then the page.
5926 header.PageVersion = 0;
5927 header.PageLength = 0;
5928 header.PageNumber = 2;
5929 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5930 cfg.cfghdr.hdr = &header;
5931 cfg.physAddr = -1;
5932 cfg.pageAddr = 0;
5933 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5934 cfg.dir = 0;
5935 cfg.timeout = 0;
5936 if (mpt_config(ioc, &cfg) != 0)
5937 return -EFAULT;
5939 if (header.PageLength == 0)
5940 return -EFAULT;
5942 iocpage2sz = header.PageLength * 4;
5943 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5944 if (!pIoc2)
5945 return -ENOMEM;
5947 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5948 cfg.physAddr = ioc2_dma;
5949 if (mpt_config(ioc, &cfg) != 0)
5950 goto out;
5952 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5953 if (!mem)
5954 goto out;
5956 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5957 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5959 mpt_read_ioc_pg_3(ioc);
5961 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5962 mpt_inactive_raid_volumes(ioc,
5963 pIoc2->RaidVolume[i].VolumeBus,
5964 pIoc2->RaidVolume[i].VolumeID);
5966 out:
5967 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5969 return rc;
5972 static int
5973 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5975 IOCPage3_t *pIoc3;
5976 u8 *mem;
5977 CONFIGPARMS cfg;
5978 ConfigPageHeader_t header;
5979 dma_addr_t ioc3_dma;
5980 int iocpage3sz = 0;
5982 /* Free the old page
5984 kfree(ioc->raid_data.pIocPg3);
5985 ioc->raid_data.pIocPg3 = NULL;
5987 /* There is at least one physical disk.
5988 * Read and save IOC Page 3
5990 header.PageVersion = 0;
5991 header.PageLength = 0;
5992 header.PageNumber = 3;
5993 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5994 cfg.cfghdr.hdr = &header;
5995 cfg.physAddr = -1;
5996 cfg.pageAddr = 0;
5997 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5998 cfg.dir = 0;
5999 cfg.timeout = 0;
6000 if (mpt_config(ioc, &cfg) != 0)
6001 return 0;
6003 if (header.PageLength == 0)
6004 return 0;
6006 /* Read Header good, alloc memory
6008 iocpage3sz = header.PageLength * 4;
6009 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6010 if (!pIoc3)
6011 return 0;
6013 /* Read the Page and save the data
6014 * into malloc'd memory.
6016 cfg.physAddr = ioc3_dma;
6017 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6018 if (mpt_config(ioc, &cfg) == 0) {
6019 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6020 if (mem) {
6021 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6022 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6026 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6028 return 0;
6031 static void
6032 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6034 IOCPage4_t *pIoc4;
6035 CONFIGPARMS cfg;
6036 ConfigPageHeader_t header;
6037 dma_addr_t ioc4_dma;
6038 int iocpage4sz;
6040 /* Read and save IOC Page 4
6042 header.PageVersion = 0;
6043 header.PageLength = 0;
6044 header.PageNumber = 4;
6045 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6046 cfg.cfghdr.hdr = &header;
6047 cfg.physAddr = -1;
6048 cfg.pageAddr = 0;
6049 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6050 cfg.dir = 0;
6051 cfg.timeout = 0;
6052 if (mpt_config(ioc, &cfg) != 0)
6053 return;
6055 if (header.PageLength == 0)
6056 return;
6058 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6059 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6060 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6061 if (!pIoc4)
6062 return;
6063 ioc->alloc_total += iocpage4sz;
6064 } else {
6065 ioc4_dma = ioc->spi_data.IocPg4_dma;
6066 iocpage4sz = ioc->spi_data.IocPg4Sz;
6069 /* Read the Page into dma memory.
6071 cfg.physAddr = ioc4_dma;
6072 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6073 if (mpt_config(ioc, &cfg) == 0) {
6074 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6075 ioc->spi_data.IocPg4_dma = ioc4_dma;
6076 ioc->spi_data.IocPg4Sz = iocpage4sz;
6077 } else {
6078 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6079 ioc->spi_data.pIocPg4 = NULL;
6080 ioc->alloc_total -= iocpage4sz;
6084 static void
6085 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6087 IOCPage1_t *pIoc1;
6088 CONFIGPARMS cfg;
6089 ConfigPageHeader_t header;
6090 dma_addr_t ioc1_dma;
6091 int iocpage1sz = 0;
6092 u32 tmp;
6094 /* Check the Coalescing Timeout in IOC Page 1
6096 header.PageVersion = 0;
6097 header.PageLength = 0;
6098 header.PageNumber = 1;
6099 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6100 cfg.cfghdr.hdr = &header;
6101 cfg.physAddr = -1;
6102 cfg.pageAddr = 0;
6103 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6104 cfg.dir = 0;
6105 cfg.timeout = 0;
6106 if (mpt_config(ioc, &cfg) != 0)
6107 return;
6109 if (header.PageLength == 0)
6110 return;
6112 /* Read Header good, alloc memory
6114 iocpage1sz = header.PageLength * 4;
6115 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6116 if (!pIoc1)
6117 return;
6119 /* Read the Page and check coalescing timeout
6121 cfg.physAddr = ioc1_dma;
6122 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6123 if (mpt_config(ioc, &cfg) == 0) {
6125 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6126 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6127 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6129 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6130 ioc->name, tmp));
6132 if (tmp > MPT_COALESCING_TIMEOUT) {
6133 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6135 /* Write NVRAM and current
6137 cfg.dir = 1;
6138 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6139 if (mpt_config(ioc, &cfg) == 0) {
6140 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6141 ioc->name, MPT_COALESCING_TIMEOUT));
6143 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6144 if (mpt_config(ioc, &cfg) == 0) {
6145 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6146 "Reset NVRAM Coalescing Timeout to = %d\n",
6147 ioc->name, MPT_COALESCING_TIMEOUT));
6148 } else {
6149 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6150 "Reset NVRAM Coalescing Timeout Failed\n",
6151 ioc->name));
6154 } else {
6155 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6156 "Reset of Current Coalescing Timeout Failed!\n",
6157 ioc->name));
6161 } else {
6162 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6166 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6168 return;
6171 static void
6172 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6174 CONFIGPARMS cfg;
6175 ConfigPageHeader_t hdr;
6176 dma_addr_t buf_dma;
6177 ManufacturingPage0_t *pbuf = NULL;
6179 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6180 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6182 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6183 cfg.cfghdr.hdr = &hdr;
6184 cfg.physAddr = -1;
6185 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6186 cfg.timeout = 10;
6188 if (mpt_config(ioc, &cfg) != 0)
6189 goto out;
6191 if (!cfg.cfghdr.hdr->PageLength)
6192 goto out;
6194 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6195 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6196 if (!pbuf)
6197 goto out;
6199 cfg.physAddr = buf_dma;
6201 if (mpt_config(ioc, &cfg) != 0)
6202 goto out;
6204 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6205 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6206 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6208 out:
6210 if (pbuf)
6211 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6214 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6216 * SendEventNotification - Send EventNotification (on or off) request to adapter
6217 * @ioc: Pointer to MPT_ADAPTER structure
6218 * @EvSwitch: Event switch flags
6219 * @sleepFlag: Specifies whether the process can sleep
6221 static int
6222 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6224 EventNotification_t evn;
6225 MPIDefaultReply_t reply_buf;
6227 memset(&evn, 0, sizeof(EventNotification_t));
6228 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6230 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6231 evn.Switch = EvSwitch;
6232 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6234 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6235 "Sending EventNotification (%d) request %p\n",
6236 ioc->name, EvSwitch, &evn));
6238 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6239 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6240 sleepFlag);
6243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6245 * SendEventAck - Send EventAck request to MPT adapter.
6246 * @ioc: Pointer to MPT_ADAPTER structure
6247 * @evnp: Pointer to original EventNotification request
6249 static int
6250 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6252 EventAck_t *pAck;
6254 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6255 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6256 ioc->name, __func__));
6257 return -1;
6260 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6262 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6263 pAck->ChainOffset = 0;
6264 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6265 pAck->MsgFlags = 0;
6266 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6267 pAck->Event = evnp->Event;
6268 pAck->EventContext = evnp->EventContext;
6270 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6272 return 0;
6275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6277 * mpt_config - Generic function to issue config message
6278 * @ioc: Pointer to an adapter structure
6279 * @pCfg: Pointer to a configuration structure. Struct contains
6280 * action, page address, direction, physical address
6281 * and pointer to a configuration page header
6282 * Page header is updated.
6284 * Returns 0 for success
6285 * -EPERM if not allowed due to ISR context
6286 * -EAGAIN if no msg frames currently available
6287 * -EFAULT for non-successful reply or no reply (timeout)
6290 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6292 Config_t *pReq;
6293 ConfigReply_t *pReply;
6294 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6295 MPT_FRAME_HDR *mf;
6296 int ii;
6297 int flagsLength;
6298 long timeout;
6299 int ret;
6300 u8 page_type = 0, extend_page;
6301 unsigned long timeleft;
6302 unsigned long flags;
6303 int in_isr;
6304 u8 issue_hard_reset = 0;
6305 u8 retry_count = 0;
6307 /* Prevent calling wait_event() (below), if caller happens
6308 * to be in ISR context, because that is fatal!
6310 in_isr = in_interrupt();
6311 if (in_isr) {
6312 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6313 ioc->name));
6314 return -EPERM;
6317 /* don't send a config page during diag reset */
6318 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6319 if (ioc->ioc_reset_in_progress) {
6320 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6321 "%s: busy with host reset\n", ioc->name, __func__));
6322 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6323 return -EBUSY;
6325 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6327 /* don't send if no chance of success */
6328 if (!ioc->active ||
6329 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6330 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6331 "%s: ioc not operational, %d, %xh\n",
6332 ioc->name, __func__, ioc->active,
6333 mpt_GetIocState(ioc, 0)));
6334 return -EFAULT;
6337 retry_config:
6338 mutex_lock(&ioc->mptbase_cmds.mutex);
6339 /* init the internal cmd struct */
6340 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6341 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6343 /* Get and Populate a free Frame
6345 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6346 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6347 "mpt_config: no msg frames!\n", ioc->name));
6348 ret = -EAGAIN;
6349 goto out;
6352 pReq = (Config_t *)mf;
6353 pReq->Action = pCfg->action;
6354 pReq->Reserved = 0;
6355 pReq->ChainOffset = 0;
6356 pReq->Function = MPI_FUNCTION_CONFIG;
6358 /* Assume page type is not extended and clear "reserved" fields. */
6359 pReq->ExtPageLength = 0;
6360 pReq->ExtPageType = 0;
6361 pReq->MsgFlags = 0;
6363 for (ii=0; ii < 8; ii++)
6364 pReq->Reserved2[ii] = 0;
6366 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6367 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6368 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6369 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6371 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6372 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6373 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6374 pReq->ExtPageType = pExtHdr->ExtPageType;
6375 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6377 /* Page Length must be treated as a reserved field for the
6378 * extended header.
6380 pReq->Header.PageLength = 0;
6383 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6385 /* Add a SGE to the config request.
6387 if (pCfg->dir)
6388 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6389 else
6390 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6392 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6393 MPI_CONFIG_PAGETYPE_EXTENDED) {
6394 flagsLength |= pExtHdr->ExtPageLength * 4;
6395 page_type = pReq->ExtPageType;
6396 extend_page = 1;
6397 } else {
6398 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6399 page_type = pReq->Header.PageType;
6400 extend_page = 0;
6403 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6404 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6405 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6407 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6408 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6409 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6410 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6411 timeout);
6412 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6413 ret = -ETIME;
6414 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6415 "Failed Sending Config request type 0x%x, page 0x%x,"
6416 " action %d, status %xh, time left %ld\n\n",
6417 ioc->name, page_type, pReq->Header.PageNumber,
6418 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6419 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6420 goto out;
6421 if (!timeleft)
6422 issue_hard_reset = 1;
6423 goto out;
6426 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6427 ret = -1;
6428 goto out;
6430 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6431 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6432 if (ret == MPI_IOCSTATUS_SUCCESS) {
6433 if (extend_page) {
6434 pCfg->cfghdr.ehdr->ExtPageLength =
6435 le16_to_cpu(pReply->ExtPageLength);
6436 pCfg->cfghdr.ehdr->ExtPageType =
6437 pReply->ExtPageType;
6439 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6440 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6441 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6442 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6446 if (retry_count)
6447 printk(MYIOC_s_INFO_FMT "Retry completed "
6448 "ret=0x%x timeleft=%ld\n",
6449 ioc->name, ret, timeleft);
6451 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6452 ret, le32_to_cpu(pReply->IOCLogInfo)));
6454 out:
6456 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6457 mutex_unlock(&ioc->mptbase_cmds.mutex);
6458 if (issue_hard_reset) {
6459 issue_hard_reset = 0;
6460 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6461 ioc->name, __func__);
6462 if (retry_count == 0) {
6463 if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6464 retry_count++;
6465 } else
6466 mpt_HardResetHandler(ioc, CAN_SLEEP);
6468 mpt_free_msg_frame(ioc, mf);
6469 /* attempt one retry for a timed out command */
6470 if (retry_count < 2) {
6471 printk(MYIOC_s_INFO_FMT
6472 "Attempting Retry Config request"
6473 " type 0x%x, page 0x%x,"
6474 " action %d\n", ioc->name, page_type,
6475 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6476 retry_count++;
6477 goto retry_config;
6480 return ret;
6484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6486 * mpt_ioc_reset - Base cleanup for hard reset
6487 * @ioc: Pointer to the adapter structure
6488 * @reset_phase: Indicates pre- or post-reset functionality
6490 * Remark: Frees resources with internally generated commands.
6492 static int
6493 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6495 switch (reset_phase) {
6496 case MPT_IOC_SETUP_RESET:
6497 ioc->taskmgmt_quiesce_io = 1;
6498 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6499 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6500 break;
6501 case MPT_IOC_PRE_RESET:
6502 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6503 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6504 break;
6505 case MPT_IOC_POST_RESET:
6506 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6507 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6508 /* wake up mptbase_cmds */
6509 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6510 ioc->mptbase_cmds.status |=
6511 MPT_MGMT_STATUS_DID_IOCRESET;
6512 complete(&ioc->mptbase_cmds.done);
6514 /* wake up taskmgmt_cmds */
6515 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6516 ioc->taskmgmt_cmds.status |=
6517 MPT_MGMT_STATUS_DID_IOCRESET;
6518 complete(&ioc->taskmgmt_cmds.done);
6520 break;
6521 default:
6522 break;
6525 return 1; /* currently means nothing really */
6529 #ifdef CONFIG_PROC_FS /* { */
6530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6532 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6536 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6538 * Returns 0 for success, non-zero for failure.
6540 static int
6541 procmpt_create(void)
6543 struct proc_dir_entry *ent;
6545 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6546 if (mpt_proc_root_dir == NULL)
6547 return -ENOTDIR;
6549 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6550 if (ent)
6551 ent->read_proc = procmpt_summary_read;
6553 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6554 if (ent)
6555 ent->read_proc = procmpt_version_read;
6557 return 0;
6560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6562 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6564 * Returns 0 for success, non-zero for failure.
6566 static void
6567 procmpt_destroy(void)
6569 remove_proc_entry("version", mpt_proc_root_dir);
6570 remove_proc_entry("summary", mpt_proc_root_dir);
6571 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6576 * procmpt_summary_read - Handle read request of a summary file
6577 * @buf: Pointer to area to write information
6578 * @start: Pointer to start pointer
6579 * @offset: Offset to start writing
6580 * @request: Amount of read data requested
6581 * @eof: Pointer to EOF integer
6582 * @data: Pointer
6584 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6585 * Returns number of characters written to process performing the read.
6587 static int
6588 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6590 MPT_ADAPTER *ioc;
6591 char *out = buf;
6592 int len;
6594 if (data) {
6595 int more = 0;
6597 ioc = data;
6598 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6600 out += more;
6601 } else {
6602 list_for_each_entry(ioc, &ioc_list, list) {
6603 int more = 0;
6605 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6607 out += more;
6608 if ((out-buf) >= request)
6609 break;
6613 len = out - buf;
6615 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6620 * procmpt_version_read - Handle read request from /proc/mpt/version.
6621 * @buf: Pointer to area to write information
6622 * @start: Pointer to start pointer
6623 * @offset: Offset to start writing
6624 * @request: Amount of read data requested
6625 * @eof: Pointer to EOF integer
6626 * @data: Pointer
6628 * Returns number of characters written to process performing the read.
6630 static int
6631 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6633 u8 cb_idx;
6634 int scsi, fc, sas, lan, ctl, targ, dmp;
6635 char *drvname;
6636 int len;
6638 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6639 len += sprintf(buf+len, " Fusion MPT base driver\n");
6641 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6642 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6643 drvname = NULL;
6644 if (MptCallbacks[cb_idx]) {
6645 switch (MptDriverClass[cb_idx]) {
6646 case MPTSPI_DRIVER:
6647 if (!scsi++) drvname = "SPI host";
6648 break;
6649 case MPTFC_DRIVER:
6650 if (!fc++) drvname = "FC host";
6651 break;
6652 case MPTSAS_DRIVER:
6653 if (!sas++) drvname = "SAS host";
6654 break;
6655 case MPTLAN_DRIVER:
6656 if (!lan++) drvname = "LAN";
6657 break;
6658 case MPTSTM_DRIVER:
6659 if (!targ++) drvname = "SCSI target";
6660 break;
6661 case MPTCTL_DRIVER:
6662 if (!ctl++) drvname = "ioctl";
6663 break;
6666 if (drvname)
6667 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6671 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6676 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6677 * @buf: Pointer to area to write information
6678 * @start: Pointer to start pointer
6679 * @offset: Offset to start writing
6680 * @request: Amount of read data requested
6681 * @eof: Pointer to EOF integer
6682 * @data: Pointer
6684 * Returns number of characters written to process performing the read.
6686 static int
6687 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6689 MPT_ADAPTER *ioc = data;
6690 int len;
6691 char expVer[32];
6692 int sz;
6693 int p;
6695 mpt_get_fw_exp_ver(expVer, ioc);
6697 len = sprintf(buf, "%s:", ioc->name);
6698 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6699 len += sprintf(buf+len, " (f/w download boot flag set)");
6700 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6701 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6703 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6704 ioc->facts.ProductID,
6705 ioc->prod_name);
6706 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6707 if (ioc->facts.FWImageSize)
6708 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6709 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6710 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6711 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6713 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6714 ioc->facts.CurrentHostMfaHighAddr);
6715 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6716 ioc->facts.CurrentSenseBufferHighAddr);
6718 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6719 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6721 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6722 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6724 * Rounding UP to nearest 4-kB boundary here...
6726 sz = (ioc->req_sz * ioc->req_depth) + 128;
6727 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6728 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6729 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6730 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6731 4*ioc->facts.RequestFrameSize,
6732 ioc->facts.GlobalCredits);
6734 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6735 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6736 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6737 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6738 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6739 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6740 ioc->facts.CurReplyFrameSize,
6741 ioc->facts.ReplyQueueDepth);
6743 len += sprintf(buf+len, " MaxDevices = %d\n",
6744 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6745 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6747 /* per-port info */
6748 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6749 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6750 p+1,
6751 ioc->facts.NumberOfPorts);
6752 if (ioc->bus_type == FC) {
6753 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6754 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6755 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6756 a[5], a[4], a[3], a[2], a[1], a[0]);
6758 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6759 ioc->fc_port_page0[p].WWNN.High,
6760 ioc->fc_port_page0[p].WWNN.Low,
6761 ioc->fc_port_page0[p].WWPN.High,
6762 ioc->fc_port_page0[p].WWPN.Low);
6766 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6769 #endif /* CONFIG_PROC_FS } */
6771 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6772 static void
6773 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6775 buf[0] ='\0';
6776 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6777 sprintf(buf, " (Exp %02d%02d)",
6778 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6779 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6781 /* insider hack! */
6782 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6783 strcat(buf, " [MDBG]");
6787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6789 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6790 * @ioc: Pointer to MPT_ADAPTER structure
6791 * @buffer: Pointer to buffer where IOC summary info should be written
6792 * @size: Pointer to number of bytes we wrote (set by this routine)
6793 * @len: Offset at which to start writing in buffer
6794 * @showlan: Display LAN stuff?
6796 * This routine writes (english readable) ASCII text, which represents
6797 * a summary of IOC information, to a buffer.
6799 void
6800 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6802 char expVer[32];
6803 int y;
6805 mpt_get_fw_exp_ver(expVer, ioc);
6808 * Shorter summary of attached ioc's...
6810 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6811 ioc->name,
6812 ioc->prod_name,
6813 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6814 ioc->facts.FWVersion.Word,
6815 expVer,
6816 ioc->facts.NumberOfPorts,
6817 ioc->req_depth);
6819 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6820 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6821 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6822 a[5], a[4], a[3], a[2], a[1], a[0]);
6825 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6827 if (!ioc->active)
6828 y += sprintf(buffer+len+y, " (disabled)");
6830 y += sprintf(buffer+len+y, "\n");
6832 *size = y;
6835 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6836 * @ioc: Pointer to MPT_ADAPTER structure
6838 * Returns 0 for SUCCESS or -1 if FAILED.
6840 * If -1 is return, then it was not possible to set the flags
6843 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6845 unsigned long flags;
6846 int retval;
6848 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6849 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6850 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6851 retval = -1;
6852 goto out;
6854 retval = 0;
6855 ioc->taskmgmt_in_progress = 1;
6856 ioc->taskmgmt_quiesce_io = 1;
6857 if (ioc->alt_ioc) {
6858 ioc->alt_ioc->taskmgmt_in_progress = 1;
6859 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6861 out:
6862 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6863 return retval;
6865 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6868 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6869 * @ioc: Pointer to MPT_ADAPTER structure
6872 void
6873 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6875 unsigned long flags;
6877 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6878 ioc->taskmgmt_in_progress = 0;
6879 ioc->taskmgmt_quiesce_io = 0;
6880 if (ioc->alt_ioc) {
6881 ioc->alt_ioc->taskmgmt_in_progress = 0;
6882 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6884 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6886 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6890 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6891 * the kernel
6892 * @ioc: Pointer to MPT_ADAPTER structure
6895 void
6896 mpt_halt_firmware(MPT_ADAPTER *ioc)
6898 u32 ioc_raw_state;
6900 ioc_raw_state = mpt_GetIocState(ioc, 0);
6902 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6903 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6904 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6905 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6906 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6907 } else {
6908 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6909 panic("%s: Firmware is halted due to command timeout\n",
6910 ioc->name);
6913 EXPORT_SYMBOL(mpt_halt_firmware);
6916 * mpt_SoftResetHandler - Issues a less expensive reset
6917 * @ioc: Pointer to MPT_ADAPTER structure
6918 * @sleepFlag: Indicates if sleep or schedule must be called.
6921 * Returns 0 for SUCCESS or -1 if FAILED.
6923 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6924 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6925 * All posted buffers are freed, and event notification is turned off.
6926 * IOC doesnt reply to any outstanding request. This will transfer IOC
6927 * to READY state.
6930 mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6932 int rc;
6933 int ii;
6934 u8 cb_idx;
6935 unsigned long flags;
6936 u32 ioc_state;
6937 unsigned long time_count;
6939 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
6940 ioc->name));
6942 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6944 if (mpt_fwfault_debug)
6945 mpt_halt_firmware(ioc);
6947 if (ioc_state == MPI_IOC_STATE_FAULT ||
6948 ioc_state == MPI_IOC_STATE_RESET) {
6949 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6950 "skipping, either in FAULT or RESET state!\n", ioc->name));
6951 return -1;
6954 if (ioc->bus_type == FC) {
6955 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6956 "skipping, because the bus type is FC!\n", ioc->name));
6957 return -1;
6960 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6961 if (ioc->ioc_reset_in_progress) {
6962 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6963 return -1;
6965 ioc->ioc_reset_in_progress = 1;
6966 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6968 rc = -1;
6970 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6971 if (MptResetHandlers[cb_idx])
6972 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6975 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6976 if (ioc->taskmgmt_in_progress) {
6977 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6978 return -1;
6980 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6981 /* Disable reply interrupts (also blocks FreeQ) */
6982 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
6983 ioc->active = 0;
6984 time_count = jiffies;
6986 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
6988 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6989 if (MptResetHandlers[cb_idx])
6990 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
6993 if (rc)
6994 goto out;
6996 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6997 if (ioc_state != MPI_IOC_STATE_READY)
6998 goto out;
7000 for (ii = 0; ii < 5; ii++) {
7001 /* Get IOC facts! Allow 5 retries */
7002 rc = GetIocFacts(ioc, sleepFlag,
7003 MPT_HOSTEVENT_IOC_RECOVER);
7004 if (rc == 0)
7005 break;
7006 if (sleepFlag == CAN_SLEEP)
7007 msleep(100);
7008 else
7009 mdelay(100);
7011 if (ii == 5)
7012 goto out;
7014 rc = PrimeIocFifos(ioc);
7015 if (rc != 0)
7016 goto out;
7018 rc = SendIocInit(ioc, sleepFlag);
7019 if (rc != 0)
7020 goto out;
7022 rc = SendEventNotification(ioc, 1, sleepFlag);
7023 if (rc != 0)
7024 goto out;
7026 if (ioc->hard_resets < -1)
7027 ioc->hard_resets++;
7030 * At this point, we know soft reset succeeded.
7033 ioc->active = 1;
7034 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7036 out:
7037 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7038 ioc->ioc_reset_in_progress = 0;
7039 ioc->taskmgmt_quiesce_io = 0;
7040 ioc->taskmgmt_in_progress = 0;
7041 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7043 if (ioc->active) { /* otherwise, hard reset coming */
7044 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7045 if (MptResetHandlers[cb_idx])
7046 mpt_signal_reset(cb_idx, ioc,
7047 MPT_IOC_POST_RESET);
7051 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7052 "SoftResetHandler: completed (%d seconds): %s\n",
7053 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7054 ((rc == 0) ? "SUCCESS" : "FAILED")));
7056 return rc;
7060 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7061 * @ioc: Pointer to MPT_ADAPTER structure
7062 * @sleepFlag: Indicates if sleep or schedule must be called.
7065 * Returns 0 for SUCCESS or -1 if FAILED.
7066 * Try for softreset first, only if it fails go for expensive
7067 * HardReset.
7070 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7071 int ret = -1;
7073 ret = mpt_SoftResetHandler(ioc, sleepFlag);
7074 if (ret == 0)
7075 return ret;
7076 ret = mpt_HardResetHandler(ioc, sleepFlag);
7077 return ret;
7079 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7081 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7083 * Reset Handling
7085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7087 * mpt_HardResetHandler - Generic reset handler
7088 * @ioc: Pointer to MPT_ADAPTER structure
7089 * @sleepFlag: Indicates if sleep or schedule must be called.
7091 * Issues SCSI Task Management call based on input arg values.
7092 * If TaskMgmt fails, returns associated SCSI request.
7094 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7095 * or a non-interrupt thread. In the former, must not call schedule().
7097 * Note: A return of -1 is a FATAL error case, as it means a
7098 * FW reload/initialization failed.
7100 * Returns 0 for SUCCESS or -1 if FAILED.
7103 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7105 int rc;
7106 u8 cb_idx;
7107 unsigned long flags;
7108 unsigned long time_count;
7110 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7111 #ifdef MFCNT
7112 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7113 printk("MF count 0x%x !\n", ioc->mfcnt);
7114 #endif
7115 if (mpt_fwfault_debug)
7116 mpt_halt_firmware(ioc);
7118 /* Reset the adapter. Prevent more than 1 call to
7119 * mpt_do_ioc_recovery at any instant in time.
7121 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7122 if (ioc->ioc_reset_in_progress) {
7123 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7124 return 0;
7126 ioc->ioc_reset_in_progress = 1;
7127 if (ioc->alt_ioc)
7128 ioc->alt_ioc->ioc_reset_in_progress = 1;
7129 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7132 /* The SCSI driver needs to adjust timeouts on all current
7133 * commands prior to the diagnostic reset being issued.
7134 * Prevents timeouts occurring during a diagnostic reset...very bad.
7135 * For all other protocol drivers, this is a no-op.
7137 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7138 if (MptResetHandlers[cb_idx]) {
7139 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7140 if (ioc->alt_ioc)
7141 mpt_signal_reset(cb_idx, ioc->alt_ioc,
7142 MPT_IOC_SETUP_RESET);
7146 time_count = jiffies;
7147 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7148 if (rc != 0) {
7149 printk(KERN_WARNING MYNAM
7150 ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name);
7151 } else {
7152 if (ioc->hard_resets < -1)
7153 ioc->hard_resets++;
7156 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7157 ioc->ioc_reset_in_progress = 0;
7158 ioc->taskmgmt_quiesce_io = 0;
7159 ioc->taskmgmt_in_progress = 0;
7160 if (ioc->alt_ioc) {
7161 ioc->alt_ioc->ioc_reset_in_progress = 0;
7162 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7163 ioc->alt_ioc->taskmgmt_in_progress = 0;
7165 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7167 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7168 if (MptResetHandlers[cb_idx]) {
7169 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7170 if (ioc->alt_ioc)
7171 mpt_signal_reset(cb_idx,
7172 ioc->alt_ioc, MPT_IOC_POST_RESET);
7176 dtmprintk(ioc,
7177 printk(MYIOC_s_DEBUG_FMT
7178 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7179 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7180 "SUCCESS" : "FAILED")));
7182 return rc;
7185 #ifdef CONFIG_FUSION_LOGGING
7186 static void
7187 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7189 char *ds = NULL;
7190 u32 evData0;
7191 int ii;
7192 u8 event;
7193 char *evStr = ioc->evStr;
7195 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7196 evData0 = le32_to_cpu(pEventReply->Data[0]);
7198 switch(event) {
7199 case MPI_EVENT_NONE:
7200 ds = "None";
7201 break;
7202 case MPI_EVENT_LOG_DATA:
7203 ds = "Log Data";
7204 break;
7205 case MPI_EVENT_STATE_CHANGE:
7206 ds = "State Change";
7207 break;
7208 case MPI_EVENT_UNIT_ATTENTION:
7209 ds = "Unit Attention";
7210 break;
7211 case MPI_EVENT_IOC_BUS_RESET:
7212 ds = "IOC Bus Reset";
7213 break;
7214 case MPI_EVENT_EXT_BUS_RESET:
7215 ds = "External Bus Reset";
7216 break;
7217 case MPI_EVENT_RESCAN:
7218 ds = "Bus Rescan Event";
7219 break;
7220 case MPI_EVENT_LINK_STATUS_CHANGE:
7221 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7222 ds = "Link Status(FAILURE) Change";
7223 else
7224 ds = "Link Status(ACTIVE) Change";
7225 break;
7226 case MPI_EVENT_LOOP_STATE_CHANGE:
7227 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7228 ds = "Loop State(LIP) Change";
7229 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7230 ds = "Loop State(LPE) Change";
7231 else
7232 ds = "Loop State(LPB) Change";
7233 break;
7234 case MPI_EVENT_LOGOUT:
7235 ds = "Logout";
7236 break;
7237 case MPI_EVENT_EVENT_CHANGE:
7238 if (evData0)
7239 ds = "Events ON";
7240 else
7241 ds = "Events OFF";
7242 break;
7243 case MPI_EVENT_INTEGRATED_RAID:
7245 u8 ReasonCode = (u8)(evData0 >> 16);
7246 switch (ReasonCode) {
7247 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7248 ds = "Integrated Raid: Volume Created";
7249 break;
7250 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7251 ds = "Integrated Raid: Volume Deleted";
7252 break;
7253 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7254 ds = "Integrated Raid: Volume Settings Changed";
7255 break;
7256 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7257 ds = "Integrated Raid: Volume Status Changed";
7258 break;
7259 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7260 ds = "Integrated Raid: Volume Physdisk Changed";
7261 break;
7262 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7263 ds = "Integrated Raid: Physdisk Created";
7264 break;
7265 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7266 ds = "Integrated Raid: Physdisk Deleted";
7267 break;
7268 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7269 ds = "Integrated Raid: Physdisk Settings Changed";
7270 break;
7271 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7272 ds = "Integrated Raid: Physdisk Status Changed";
7273 break;
7274 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7275 ds = "Integrated Raid: Domain Validation Needed";
7276 break;
7277 case MPI_EVENT_RAID_RC_SMART_DATA :
7278 ds = "Integrated Raid; Smart Data";
7279 break;
7280 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7281 ds = "Integrated Raid: Replace Action Started";
7282 break;
7283 default:
7284 ds = "Integrated Raid";
7285 break;
7287 break;
7289 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7290 ds = "SCSI Device Status Change";
7291 break;
7292 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7294 u8 id = (u8)(evData0);
7295 u8 channel = (u8)(evData0 >> 8);
7296 u8 ReasonCode = (u8)(evData0 >> 16);
7297 switch (ReasonCode) {
7298 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7299 snprintf(evStr, EVENT_DESCR_STR_SZ,
7300 "SAS Device Status Change: Added: "
7301 "id=%d channel=%d", id, channel);
7302 break;
7303 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7304 snprintf(evStr, EVENT_DESCR_STR_SZ,
7305 "SAS Device Status Change: Deleted: "
7306 "id=%d channel=%d", id, channel);
7307 break;
7308 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7309 snprintf(evStr, EVENT_DESCR_STR_SZ,
7310 "SAS Device Status Change: SMART Data: "
7311 "id=%d channel=%d", id, channel);
7312 break;
7313 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7314 snprintf(evStr, EVENT_DESCR_STR_SZ,
7315 "SAS Device Status Change: No Persistancy: "
7316 "id=%d channel=%d", id, channel);
7317 break;
7318 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7319 snprintf(evStr, EVENT_DESCR_STR_SZ,
7320 "SAS Device Status Change: Unsupported Device "
7321 "Discovered : id=%d channel=%d", id, channel);
7322 break;
7323 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7324 snprintf(evStr, EVENT_DESCR_STR_SZ,
7325 "SAS Device Status Change: Internal Device "
7326 "Reset : id=%d channel=%d", id, channel);
7327 break;
7328 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7329 snprintf(evStr, EVENT_DESCR_STR_SZ,
7330 "SAS Device Status Change: Internal Task "
7331 "Abort : id=%d channel=%d", id, channel);
7332 break;
7333 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7334 snprintf(evStr, EVENT_DESCR_STR_SZ,
7335 "SAS Device Status Change: Internal Abort "
7336 "Task Set : id=%d channel=%d", id, channel);
7337 break;
7338 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7339 snprintf(evStr, EVENT_DESCR_STR_SZ,
7340 "SAS Device Status Change: Internal Clear "
7341 "Task Set : id=%d channel=%d", id, channel);
7342 break;
7343 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7344 snprintf(evStr, EVENT_DESCR_STR_SZ,
7345 "SAS Device Status Change: Internal Query "
7346 "Task : id=%d channel=%d", id, channel);
7347 break;
7348 default:
7349 snprintf(evStr, EVENT_DESCR_STR_SZ,
7350 "SAS Device Status Change: Unknown: "
7351 "id=%d channel=%d", id, channel);
7352 break;
7354 break;
7356 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7357 ds = "Bus Timer Expired";
7358 break;
7359 case MPI_EVENT_QUEUE_FULL:
7361 u16 curr_depth = (u16)(evData0 >> 16);
7362 u8 channel = (u8)(evData0 >> 8);
7363 u8 id = (u8)(evData0);
7365 snprintf(evStr, EVENT_DESCR_STR_SZ,
7366 "Queue Full: channel=%d id=%d depth=%d",
7367 channel, id, curr_depth);
7368 break;
7370 case MPI_EVENT_SAS_SES:
7371 ds = "SAS SES Event";
7372 break;
7373 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7374 ds = "Persistent Table Full";
7375 break;
7376 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7378 u8 LinkRates = (u8)(evData0 >> 8);
7379 u8 PhyNumber = (u8)(evData0);
7380 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7381 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7382 switch (LinkRates) {
7383 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7384 snprintf(evStr, EVENT_DESCR_STR_SZ,
7385 "SAS PHY Link Status: Phy=%d:"
7386 " Rate Unknown",PhyNumber);
7387 break;
7388 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7389 snprintf(evStr, EVENT_DESCR_STR_SZ,
7390 "SAS PHY Link Status: Phy=%d:"
7391 " Phy Disabled",PhyNumber);
7392 break;
7393 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7394 snprintf(evStr, EVENT_DESCR_STR_SZ,
7395 "SAS PHY Link Status: Phy=%d:"
7396 " Failed Speed Nego",PhyNumber);
7397 break;
7398 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7399 snprintf(evStr, EVENT_DESCR_STR_SZ,
7400 "SAS PHY Link Status: Phy=%d:"
7401 " Sata OOB Completed",PhyNumber);
7402 break;
7403 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7404 snprintf(evStr, EVENT_DESCR_STR_SZ,
7405 "SAS PHY Link Status: Phy=%d:"
7406 " Rate 1.5 Gbps",PhyNumber);
7407 break;
7408 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7409 snprintf(evStr, EVENT_DESCR_STR_SZ,
7410 "SAS PHY Link Status: Phy=%d:"
7411 " Rate 3.0 Gpbs",PhyNumber);
7412 break;
7413 default:
7414 snprintf(evStr, EVENT_DESCR_STR_SZ,
7415 "SAS PHY Link Status: Phy=%d", PhyNumber);
7416 break;
7418 break;
7420 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7421 ds = "SAS Discovery Error";
7422 break;
7423 case MPI_EVENT_IR_RESYNC_UPDATE:
7425 u8 resync_complete = (u8)(evData0 >> 16);
7426 snprintf(evStr, EVENT_DESCR_STR_SZ,
7427 "IR Resync Update: Complete = %d:",resync_complete);
7428 break;
7430 case MPI_EVENT_IR2:
7432 u8 id = (u8)(evData0);
7433 u8 channel = (u8)(evData0 >> 8);
7434 u8 phys_num = (u8)(evData0 >> 24);
7435 u8 ReasonCode = (u8)(evData0 >> 16);
7437 switch (ReasonCode) {
7438 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7439 snprintf(evStr, EVENT_DESCR_STR_SZ,
7440 "IR2: LD State Changed: "
7441 "id=%d channel=%d phys_num=%d",
7442 id, channel, phys_num);
7443 break;
7444 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7445 snprintf(evStr, EVENT_DESCR_STR_SZ,
7446 "IR2: PD State Changed "
7447 "id=%d channel=%d phys_num=%d",
7448 id, channel, phys_num);
7449 break;
7450 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7451 snprintf(evStr, EVENT_DESCR_STR_SZ,
7452 "IR2: Bad Block Table Full: "
7453 "id=%d channel=%d phys_num=%d",
7454 id, channel, phys_num);
7455 break;
7456 case MPI_EVENT_IR2_RC_PD_INSERTED:
7457 snprintf(evStr, EVENT_DESCR_STR_SZ,
7458 "IR2: PD Inserted: "
7459 "id=%d channel=%d phys_num=%d",
7460 id, channel, phys_num);
7461 break;
7462 case MPI_EVENT_IR2_RC_PD_REMOVED:
7463 snprintf(evStr, EVENT_DESCR_STR_SZ,
7464 "IR2: PD Removed: "
7465 "id=%d channel=%d phys_num=%d",
7466 id, channel, phys_num);
7467 break;
7468 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7469 snprintf(evStr, EVENT_DESCR_STR_SZ,
7470 "IR2: Foreign CFG Detected: "
7471 "id=%d channel=%d phys_num=%d",
7472 id, channel, phys_num);
7473 break;
7474 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7475 snprintf(evStr, EVENT_DESCR_STR_SZ,
7476 "IR2: Rebuild Medium Error: "
7477 "id=%d channel=%d phys_num=%d",
7478 id, channel, phys_num);
7479 break;
7480 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7481 snprintf(evStr, EVENT_DESCR_STR_SZ,
7482 "IR2: Dual Port Added: "
7483 "id=%d channel=%d phys_num=%d",
7484 id, channel, phys_num);
7485 break;
7486 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7487 snprintf(evStr, EVENT_DESCR_STR_SZ,
7488 "IR2: Dual Port Removed: "
7489 "id=%d channel=%d phys_num=%d",
7490 id, channel, phys_num);
7491 break;
7492 default:
7493 ds = "IR2";
7494 break;
7496 break;
7498 case MPI_EVENT_SAS_DISCOVERY:
7500 if (evData0)
7501 ds = "SAS Discovery: Start";
7502 else
7503 ds = "SAS Discovery: Stop";
7504 break;
7506 case MPI_EVENT_LOG_ENTRY_ADDED:
7507 ds = "SAS Log Entry Added";
7508 break;
7510 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7512 u8 phy_num = (u8)(evData0);
7513 u8 port_num = (u8)(evData0 >> 8);
7514 u8 port_width = (u8)(evData0 >> 16);
7515 u8 primative = (u8)(evData0 >> 24);
7516 snprintf(evStr, EVENT_DESCR_STR_SZ,
7517 "SAS Broadcase Primative: phy=%d port=%d "
7518 "width=%d primative=0x%02x",
7519 phy_num, port_num, port_width, primative);
7520 break;
7523 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7525 u8 reason = (u8)(evData0);
7527 switch (reason) {
7528 case MPI_EVENT_SAS_INIT_RC_ADDED:
7529 ds = "SAS Initiator Status Change: Added";
7530 break;
7531 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7532 ds = "SAS Initiator Status Change: Deleted";
7533 break;
7534 default:
7535 ds = "SAS Initiator Status Change";
7536 break;
7538 break;
7541 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7543 u8 max_init = (u8)(evData0);
7544 u8 current_init = (u8)(evData0 >> 8);
7546 snprintf(evStr, EVENT_DESCR_STR_SZ,
7547 "SAS Initiator Device Table Overflow: max initiators=%02d "
7548 "current initators=%02d",
7549 max_init, current_init);
7550 break;
7552 case MPI_EVENT_SAS_SMP_ERROR:
7554 u8 status = (u8)(evData0);
7555 u8 port_num = (u8)(evData0 >> 8);
7556 u8 result = (u8)(evData0 >> 16);
7558 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7559 snprintf(evStr, EVENT_DESCR_STR_SZ,
7560 "SAS SMP Error: port=%d result=0x%02x",
7561 port_num, result);
7562 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7563 snprintf(evStr, EVENT_DESCR_STR_SZ,
7564 "SAS SMP Error: port=%d : CRC Error",
7565 port_num);
7566 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7567 snprintf(evStr, EVENT_DESCR_STR_SZ,
7568 "SAS SMP Error: port=%d : Timeout",
7569 port_num);
7570 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7571 snprintf(evStr, EVENT_DESCR_STR_SZ,
7572 "SAS SMP Error: port=%d : No Destination",
7573 port_num);
7574 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7575 snprintf(evStr, EVENT_DESCR_STR_SZ,
7576 "SAS SMP Error: port=%d : Bad Destination",
7577 port_num);
7578 else
7579 snprintf(evStr, EVENT_DESCR_STR_SZ,
7580 "SAS SMP Error: port=%d : status=0x%02x",
7581 port_num, status);
7582 break;
7585 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7587 u8 reason = (u8)(evData0);
7589 switch (reason) {
7590 case MPI_EVENT_SAS_EXP_RC_ADDED:
7591 ds = "Expander Status Change: Added";
7592 break;
7593 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7594 ds = "Expander Status Change: Deleted";
7595 break;
7596 default:
7597 ds = "Expander Status Change";
7598 break;
7600 break;
7604 * MPT base "custom" events may be added here...
7606 default:
7607 ds = "Unknown";
7608 break;
7610 if (ds)
7611 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7614 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7615 "MPT event:(%02Xh) : %s\n",
7616 ioc->name, event, evStr));
7618 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7619 ": Event data:\n"));
7620 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7621 devtverboseprintk(ioc, printk(" %08x",
7622 le32_to_cpu(pEventReply->Data[ii])));
7623 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7625 #endif
7626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7628 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7629 * @ioc: Pointer to MPT_ADAPTER structure
7630 * @pEventReply: Pointer to EventNotification reply frame
7631 * @evHandlers: Pointer to integer, number of event handlers
7633 * Routes a received EventNotificationReply to all currently registered
7634 * event handlers.
7635 * Returns sum of event handlers return values.
7637 static int
7638 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7640 u16 evDataLen;
7641 u32 evData0 = 0;
7642 int ii;
7643 u8 cb_idx;
7644 int r = 0;
7645 int handlers = 0;
7646 u8 event;
7649 * Do platform normalization of values
7651 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7652 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7653 if (evDataLen) {
7654 evData0 = le32_to_cpu(pEventReply->Data[0]);
7657 #ifdef CONFIG_FUSION_LOGGING
7658 if (evDataLen)
7659 mpt_display_event_info(ioc, pEventReply);
7660 #endif
7663 * Do general / base driver event processing
7665 switch(event) {
7666 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7667 if (evDataLen) {
7668 u8 evState = evData0 & 0xFF;
7670 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7672 /* Update EventState field in cached IocFacts */
7673 if (ioc->facts.Function) {
7674 ioc->facts.EventState = evState;
7677 break;
7678 case MPI_EVENT_INTEGRATED_RAID:
7679 mptbase_raid_process_event_data(ioc,
7680 (MpiEventDataRaid_t *)pEventReply->Data);
7681 break;
7682 default:
7683 break;
7687 * Should this event be logged? Events are written sequentially.
7688 * When buffer is full, start again at the top.
7690 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7691 int idx;
7693 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7695 ioc->events[idx].event = event;
7696 ioc->events[idx].eventContext = ioc->eventContext;
7698 for (ii = 0; ii < 2; ii++) {
7699 if (ii < evDataLen)
7700 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7701 else
7702 ioc->events[idx].data[ii] = 0;
7705 ioc->eventContext++;
7710 * Call each currently registered protocol event handler.
7712 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7713 if (MptEvHandlers[cb_idx]) {
7714 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7715 "Routing Event to event handler #%d\n",
7716 ioc->name, cb_idx));
7717 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7718 handlers++;
7721 /* FIXME? Examine results here? */
7724 * If needed, send (a single) EventAck.
7726 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7727 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7728 "EventAck required\n",ioc->name));
7729 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7730 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7731 ioc->name, ii));
7735 *evHandlers = handlers;
7736 return r;
7739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7741 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7742 * @ioc: Pointer to MPT_ADAPTER structure
7743 * @log_info: U32 LogInfo reply word from the IOC
7745 * Refer to lsi/mpi_log_fc.h.
7747 static void
7748 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7750 char *desc = "unknown";
7752 switch (log_info & 0xFF000000) {
7753 case MPI_IOCLOGINFO_FC_INIT_BASE:
7754 desc = "FCP Initiator";
7755 break;
7756 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7757 desc = "FCP Target";
7758 break;
7759 case MPI_IOCLOGINFO_FC_LAN_BASE:
7760 desc = "LAN";
7761 break;
7762 case MPI_IOCLOGINFO_FC_MSG_BASE:
7763 desc = "MPI Message Layer";
7764 break;
7765 case MPI_IOCLOGINFO_FC_LINK_BASE:
7766 desc = "FC Link";
7767 break;
7768 case MPI_IOCLOGINFO_FC_CTX_BASE:
7769 desc = "Context Manager";
7770 break;
7771 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7772 desc = "Invalid Field Offset";
7773 break;
7774 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7775 desc = "State Change Info";
7776 break;
7779 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7780 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7785 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7786 * @ioc: Pointer to MPT_ADAPTER structure
7787 * @log_info: U32 LogInfo word from the IOC
7789 * Refer to lsi/sp_log.h.
7791 static void
7792 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7794 u32 info = log_info & 0x00FF0000;
7795 char *desc = "unknown";
7797 switch (info) {
7798 case 0x00010000:
7799 desc = "bug! MID not found";
7800 break;
7802 case 0x00020000:
7803 desc = "Parity Error";
7804 break;
7806 case 0x00030000:
7807 desc = "ASYNC Outbound Overrun";
7808 break;
7810 case 0x00040000:
7811 desc = "SYNC Offset Error";
7812 break;
7814 case 0x00050000:
7815 desc = "BM Change";
7816 break;
7818 case 0x00060000:
7819 desc = "Msg In Overflow";
7820 break;
7822 case 0x00070000:
7823 desc = "DMA Error";
7824 break;
7826 case 0x00080000:
7827 desc = "Outbound DMA Overrun";
7828 break;
7830 case 0x00090000:
7831 desc = "Task Management";
7832 break;
7834 case 0x000A0000:
7835 desc = "Device Problem";
7836 break;
7838 case 0x000B0000:
7839 desc = "Invalid Phase Change";
7840 break;
7842 case 0x000C0000:
7843 desc = "Untagged Table Size";
7844 break;
7848 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7851 /* strings for sas loginfo */
7852 static char *originator_str[] = {
7853 "IOP", /* 00h */
7854 "PL", /* 01h */
7855 "IR" /* 02h */
7857 static char *iop_code_str[] = {
7858 NULL, /* 00h */
7859 "Invalid SAS Address", /* 01h */
7860 NULL, /* 02h */
7861 "Invalid Page", /* 03h */
7862 "Diag Message Error", /* 04h */
7863 "Task Terminated", /* 05h */
7864 "Enclosure Management", /* 06h */
7865 "Target Mode" /* 07h */
7867 static char *pl_code_str[] = {
7868 NULL, /* 00h */
7869 "Open Failure", /* 01h */
7870 "Invalid Scatter Gather List", /* 02h */
7871 "Wrong Relative Offset or Frame Length", /* 03h */
7872 "Frame Transfer Error", /* 04h */
7873 "Transmit Frame Connected Low", /* 05h */
7874 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7875 "SATA Read Log Receive Data Error", /* 07h */
7876 "SATA NCQ Fail All Commands After Error", /* 08h */
7877 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7878 "Receive Frame Invalid Message", /* 0Ah */
7879 "Receive Context Message Valid Error", /* 0Bh */
7880 "Receive Frame Current Frame Error", /* 0Ch */
7881 "SATA Link Down", /* 0Dh */
7882 "Discovery SATA Init W IOS", /* 0Eh */
7883 "Config Invalid Page", /* 0Fh */
7884 "Discovery SATA Init Timeout", /* 10h */
7885 "Reset", /* 11h */
7886 "Abort", /* 12h */
7887 "IO Not Yet Executed", /* 13h */
7888 "IO Executed", /* 14h */
7889 "Persistent Reservation Out Not Affiliation "
7890 "Owner", /* 15h */
7891 "Open Transmit DMA Abort", /* 16h */
7892 "IO Device Missing Delay Retry", /* 17h */
7893 "IO Cancelled Due to Recieve Error", /* 18h */
7894 NULL, /* 19h */
7895 NULL, /* 1Ah */
7896 NULL, /* 1Bh */
7897 NULL, /* 1Ch */
7898 NULL, /* 1Dh */
7899 NULL, /* 1Eh */
7900 NULL, /* 1Fh */
7901 "Enclosure Management" /* 20h */
7903 static char *ir_code_str[] = {
7904 "Raid Action Error", /* 00h */
7905 NULL, /* 00h */
7906 NULL, /* 01h */
7907 NULL, /* 02h */
7908 NULL, /* 03h */
7909 NULL, /* 04h */
7910 NULL, /* 05h */
7911 NULL, /* 06h */
7912 NULL /* 07h */
7914 static char *raid_sub_code_str[] = {
7915 NULL, /* 00h */
7916 "Volume Creation Failed: Data Passed too "
7917 "Large", /* 01h */
7918 "Volume Creation Failed: Duplicate Volumes "
7919 "Attempted", /* 02h */
7920 "Volume Creation Failed: Max Number "
7921 "Supported Volumes Exceeded", /* 03h */
7922 "Volume Creation Failed: DMA Error", /* 04h */
7923 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7924 "Volume Creation Failed: Error Reading "
7925 "MFG Page 4", /* 06h */
7926 "Volume Creation Failed: Creating Internal "
7927 "Structures", /* 07h */
7928 NULL, /* 08h */
7929 NULL, /* 09h */
7930 NULL, /* 0Ah */
7931 NULL, /* 0Bh */
7932 NULL, /* 0Ch */
7933 NULL, /* 0Dh */
7934 NULL, /* 0Eh */
7935 NULL, /* 0Fh */
7936 "Activation failed: Already Active Volume", /* 10h */
7937 "Activation failed: Unsupported Volume Type", /* 11h */
7938 "Activation failed: Too Many Active Volumes", /* 12h */
7939 "Activation failed: Volume ID in Use", /* 13h */
7940 "Activation failed: Reported Failure", /* 14h */
7941 "Activation failed: Importing a Volume", /* 15h */
7942 NULL, /* 16h */
7943 NULL, /* 17h */
7944 NULL, /* 18h */
7945 NULL, /* 19h */
7946 NULL, /* 1Ah */
7947 NULL, /* 1Bh */
7948 NULL, /* 1Ch */
7949 NULL, /* 1Dh */
7950 NULL, /* 1Eh */
7951 NULL, /* 1Fh */
7952 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7953 "Phys Disk failed: Data Passed too Large", /* 21h */
7954 "Phys Disk failed: DMA Error", /* 22h */
7955 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7956 "Phys Disk failed: Creating Phys Disk Config "
7957 "Page", /* 24h */
7958 NULL, /* 25h */
7959 NULL, /* 26h */
7960 NULL, /* 27h */
7961 NULL, /* 28h */
7962 NULL, /* 29h */
7963 NULL, /* 2Ah */
7964 NULL, /* 2Bh */
7965 NULL, /* 2Ch */
7966 NULL, /* 2Dh */
7967 NULL, /* 2Eh */
7968 NULL, /* 2Fh */
7969 "Compatibility Error: IR Disabled", /* 30h */
7970 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7971 "Compatibility Error: Device not Direct Access "
7972 "Device ", /* 32h */
7973 "Compatibility Error: Removable Device Found", /* 33h */
7974 "Compatibility Error: Device SCSI Version not "
7975 "2 or Higher", /* 34h */
7976 "Compatibility Error: SATA Device, 48 BIT LBA "
7977 "not Supported", /* 35h */
7978 "Compatibility Error: Device doesn't have "
7979 "512 Byte Block Sizes", /* 36h */
7980 "Compatibility Error: Volume Type Check Failed", /* 37h */
7981 "Compatibility Error: Volume Type is "
7982 "Unsupported by FW", /* 38h */
7983 "Compatibility Error: Disk Drive too Small for "
7984 "use in Volume", /* 39h */
7985 "Compatibility Error: Phys Disk for Create "
7986 "Volume not Found", /* 3Ah */
7987 "Compatibility Error: Too Many or too Few "
7988 "Disks for Volume Type", /* 3Bh */
7989 "Compatibility Error: Disk stripe Sizes "
7990 "Must be 64KB", /* 3Ch */
7991 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7996 * mpt_sas_log_info - Log information returned from SAS IOC.
7997 * @ioc: Pointer to MPT_ADAPTER structure
7998 * @log_info: U32 LogInfo reply word from the IOC
8000 * Refer to lsi/mpi_log_sas.h.
8002 static void
8003 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
8005 union loginfo_type {
8006 u32 loginfo;
8007 struct {
8008 u32 subcode:16;
8009 u32 code:8;
8010 u32 originator:4;
8011 u32 bus_type:4;
8012 }dw;
8014 union loginfo_type sas_loginfo;
8015 char *originator_desc = NULL;
8016 char *code_desc = NULL;
8017 char *sub_code_desc = NULL;
8019 sas_loginfo.loginfo = log_info;
8020 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8021 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8022 return;
8024 originator_desc = originator_str[sas_loginfo.dw.originator];
8026 switch (sas_loginfo.dw.originator) {
8028 case 0: /* IOP */
8029 if (sas_loginfo.dw.code <
8030 ARRAY_SIZE(iop_code_str))
8031 code_desc = iop_code_str[sas_loginfo.dw.code];
8032 break;
8033 case 1: /* PL */
8034 if (sas_loginfo.dw.code <
8035 ARRAY_SIZE(pl_code_str))
8036 code_desc = pl_code_str[sas_loginfo.dw.code];
8037 break;
8038 case 2: /* IR */
8039 if (sas_loginfo.dw.code >=
8040 ARRAY_SIZE(ir_code_str))
8041 break;
8042 code_desc = ir_code_str[sas_loginfo.dw.code];
8043 if (sas_loginfo.dw.subcode >=
8044 ARRAY_SIZE(raid_sub_code_str))
8045 break;
8046 if (sas_loginfo.dw.code == 0)
8047 sub_code_desc =
8048 raid_sub_code_str[sas_loginfo.dw.subcode];
8049 break;
8050 default:
8051 return;
8054 if (sub_code_desc != NULL)
8055 printk(MYIOC_s_INFO_FMT
8056 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8057 " SubCode={%s}\n",
8058 ioc->name, log_info, originator_desc, code_desc,
8059 sub_code_desc);
8060 else if (code_desc != NULL)
8061 printk(MYIOC_s_INFO_FMT
8062 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8063 " SubCode(0x%04x)\n",
8064 ioc->name, log_info, originator_desc, code_desc,
8065 sas_loginfo.dw.subcode);
8066 else
8067 printk(MYIOC_s_INFO_FMT
8068 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8069 " SubCode(0x%04x)\n",
8070 ioc->name, log_info, originator_desc,
8071 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
8074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8076 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8077 * @ioc: Pointer to MPT_ADAPTER structure
8078 * @ioc_status: U32 IOCStatus word from IOC
8079 * @mf: Pointer to MPT request frame
8081 * Refer to lsi/mpi.h.
8083 static void
8084 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8086 Config_t *pReq = (Config_t *)mf;
8087 char extend_desc[EVENT_DESCR_STR_SZ];
8088 char *desc = NULL;
8089 u32 form;
8090 u8 page_type;
8092 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8093 page_type = pReq->ExtPageType;
8094 else
8095 page_type = pReq->Header.PageType;
8098 * ignore invalid page messages for GET_NEXT_HANDLE
8100 form = le32_to_cpu(pReq->PageAddress);
8101 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8102 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8103 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8104 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8105 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8106 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8107 return;
8109 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8110 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8111 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8112 return;
8115 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8116 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8117 page_type, pReq->Header.PageNumber, pReq->Action, form);
8119 switch (ioc_status) {
8121 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8122 desc = "Config Page Invalid Action";
8123 break;
8125 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8126 desc = "Config Page Invalid Type";
8127 break;
8129 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8130 desc = "Config Page Invalid Page";
8131 break;
8133 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8134 desc = "Config Page Invalid Data";
8135 break;
8137 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8138 desc = "Config Page No Defaults";
8139 break;
8141 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8142 desc = "Config Page Can't Commit";
8143 break;
8146 if (!desc)
8147 return;
8149 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8150 ioc->name, ioc_status, desc, extend_desc));
8154 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8155 * @ioc: Pointer to MPT_ADAPTER structure
8156 * @ioc_status: U32 IOCStatus word from IOC
8157 * @mf: Pointer to MPT request frame
8159 * Refer to lsi/mpi.h.
8161 static void
8162 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8164 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8165 char *desc = NULL;
8167 switch (status) {
8169 /****************************************************************************/
8170 /* Common IOCStatus values for all replies */
8171 /****************************************************************************/
8173 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8174 desc = "Invalid Function";
8175 break;
8177 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8178 desc = "Busy";
8179 break;
8181 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8182 desc = "Invalid SGL";
8183 break;
8185 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8186 desc = "Internal Error";
8187 break;
8189 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8190 desc = "Reserved";
8191 break;
8193 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8194 desc = "Insufficient Resources";
8195 break;
8197 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8198 desc = "Invalid Field";
8199 break;
8201 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8202 desc = "Invalid State";
8203 break;
8205 /****************************************************************************/
8206 /* Config IOCStatus values */
8207 /****************************************************************************/
8209 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8210 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8211 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8212 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8213 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8214 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8215 mpt_iocstatus_info_config(ioc, status, mf);
8216 break;
8218 /****************************************************************************/
8219 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8220 /* */
8221 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8222 /* */
8223 /****************************************************************************/
8225 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8226 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8227 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8228 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8229 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8230 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8231 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8232 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8233 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8234 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8235 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8236 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8237 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8238 break;
8240 /****************************************************************************/
8241 /* SCSI Target values */
8242 /****************************************************************************/
8244 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8245 desc = "Target: Priority IO";
8246 break;
8248 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8249 desc = "Target: Invalid Port";
8250 break;
8252 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8253 desc = "Target Invalid IO Index:";
8254 break;
8256 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8257 desc = "Target: Aborted";
8258 break;
8260 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8261 desc = "Target: No Conn Retryable";
8262 break;
8264 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8265 desc = "Target: No Connection";
8266 break;
8268 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8269 desc = "Target: Transfer Count Mismatch";
8270 break;
8272 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8273 desc = "Target: STS Data not Sent";
8274 break;
8276 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8277 desc = "Target: Data Offset Error";
8278 break;
8280 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8281 desc = "Target: Too Much Write Data";
8282 break;
8284 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8285 desc = "Target: IU Too Short";
8286 break;
8288 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8289 desc = "Target: ACK NAK Timeout";
8290 break;
8292 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8293 desc = "Target: Nak Received";
8294 break;
8296 /****************************************************************************/
8297 /* Fibre Channel Direct Access values */
8298 /****************************************************************************/
8300 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8301 desc = "FC: Aborted";
8302 break;
8304 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8305 desc = "FC: RX ID Invalid";
8306 break;
8308 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8309 desc = "FC: DID Invalid";
8310 break;
8312 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8313 desc = "FC: Node Logged Out";
8314 break;
8316 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8317 desc = "FC: Exchange Canceled";
8318 break;
8320 /****************************************************************************/
8321 /* LAN values */
8322 /****************************************************************************/
8324 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8325 desc = "LAN: Device not Found";
8326 break;
8328 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8329 desc = "LAN: Device Failure";
8330 break;
8332 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8333 desc = "LAN: Transmit Error";
8334 break;
8336 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8337 desc = "LAN: Transmit Aborted";
8338 break;
8340 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8341 desc = "LAN: Receive Error";
8342 break;
8344 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8345 desc = "LAN: Receive Aborted";
8346 break;
8348 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8349 desc = "LAN: Partial Packet";
8350 break;
8352 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8353 desc = "LAN: Canceled";
8354 break;
8356 /****************************************************************************/
8357 /* Serial Attached SCSI values */
8358 /****************************************************************************/
8360 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8361 desc = "SAS: SMP Request Failed";
8362 break;
8364 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8365 desc = "SAS: SMP Data Overrun";
8366 break;
8368 default:
8369 desc = "Others";
8370 break;
8373 if (!desc)
8374 return;
8376 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8377 ioc->name, status, desc));
8380 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8381 EXPORT_SYMBOL(mpt_attach);
8382 EXPORT_SYMBOL(mpt_detach);
8383 #ifdef CONFIG_PM
8384 EXPORT_SYMBOL(mpt_resume);
8385 EXPORT_SYMBOL(mpt_suspend);
8386 #endif
8387 EXPORT_SYMBOL(ioc_list);
8388 EXPORT_SYMBOL(mpt_register);
8389 EXPORT_SYMBOL(mpt_deregister);
8390 EXPORT_SYMBOL(mpt_event_register);
8391 EXPORT_SYMBOL(mpt_event_deregister);
8392 EXPORT_SYMBOL(mpt_reset_register);
8393 EXPORT_SYMBOL(mpt_reset_deregister);
8394 EXPORT_SYMBOL(mpt_device_driver_register);
8395 EXPORT_SYMBOL(mpt_device_driver_deregister);
8396 EXPORT_SYMBOL(mpt_get_msg_frame);
8397 EXPORT_SYMBOL(mpt_put_msg_frame);
8398 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8399 EXPORT_SYMBOL(mpt_free_msg_frame);
8400 EXPORT_SYMBOL(mpt_send_handshake_request);
8401 EXPORT_SYMBOL(mpt_verify_adapter);
8402 EXPORT_SYMBOL(mpt_GetIocState);
8403 EXPORT_SYMBOL(mpt_print_ioc_summary);
8404 EXPORT_SYMBOL(mpt_HardResetHandler);
8405 EXPORT_SYMBOL(mpt_config);
8406 EXPORT_SYMBOL(mpt_findImVolumes);
8407 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8408 EXPORT_SYMBOL(mpt_free_fw_memory);
8409 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8410 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8412 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8414 * fusion_init - Fusion MPT base driver initialization routine.
8416 * Returns 0 for success, non-zero for failure.
8418 static int __init
8419 fusion_init(void)
8421 u8 cb_idx;
8423 show_mptmod_ver(my_NAME, my_VERSION);
8424 printk(KERN_INFO COPYRIGHT "\n");
8426 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8427 MptCallbacks[cb_idx] = NULL;
8428 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8429 MptEvHandlers[cb_idx] = NULL;
8430 MptResetHandlers[cb_idx] = NULL;
8433 /* Register ourselves (mptbase) in order to facilitate
8434 * EventNotification handling.
8436 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
8438 /* Register for hard reset handling callbacks.
8440 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8442 #ifdef CONFIG_PROC_FS
8443 (void) procmpt_create();
8444 #endif
8445 return 0;
8448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8450 * fusion_exit - Perform driver unload cleanup.
8452 * This routine frees all resources associated with each MPT adapter
8453 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8455 static void __exit
8456 fusion_exit(void)
8459 mpt_reset_deregister(mpt_base_index);
8461 #ifdef CONFIG_PROC_FS
8462 procmpt_destroy();
8463 #endif
8466 module_init(fusion_init);
8467 module_exit(fusion_exit);