]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame_incremental - drivers/message/fusion/mptbase.c
[SCSI] mpt fusion: Fixing 1078 data corruption issue for 36GB memory region
[mirror_ubuntu-bionic-kernel.git] / drivers / message / fusion / mptbase.c
... / ...
CommitLineData
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.
7 *
8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
10 *
11 */
12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
13/*
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.
17
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.
22
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.
33
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
42
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
46*/
47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48
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
65
66#include "mptbase.h"
67#include "lsi/mpi_log_fc.h"
68
69/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70#define my_NAME "Fusion MPT base driver"
71#define my_VERSION MPT_LINUX_VERSION_COMMON
72#define MYNAM "mptbase"
73
74MODULE_AUTHOR(MODULEAUTHOR);
75MODULE_DESCRIPTION(my_NAME);
76MODULE_LICENSE("GPL");
77MODULE_VERSION(my_VERSION);
78
79/*
80 * cmd line parameters
81 */
82
83static int mpt_msi_enable_spi;
84module_param(mpt_msi_enable_spi, int, 0);
85MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
86 controllers (default=0)");
87
88static int mpt_msi_enable_fc;
89module_param(mpt_msi_enable_fc, int, 0);
90MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
91 controllers (default=0)");
92
93static int mpt_msi_enable_sas;
94module_param(mpt_msi_enable_sas, int, 0);
95MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
96 controllers (default=0)");
97
98
99static int mpt_channel_mapping;
100module_param(mpt_channel_mapping, int, 0);
101MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
102
103static int mpt_debug_level;
104static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
105module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
106 &mpt_debug_level, 0600);
107MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
108 - (default=0)");
109
110int mpt_fwfault_debug;
111EXPORT_SYMBOL(mpt_fwfault_debug);
112module_param_call(mpt_fwfault_debug, param_set_int, param_get_int,
113 &mpt_fwfault_debug, 0600);
114MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
116
117
118
119#ifdef MFCNT
120static int mfcounter = 0;
121#define PRINT_MF_COUNT 20000
122#endif
123
124/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
125/*
126 * Public data...
127 */
128
129static struct proc_dir_entry *mpt_proc_root_dir;
130
131#define WHOINIT_UNKNOWN 0xAA
132
133/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
134/*
135 * Private data...
136 */
137 /* Adapter link list */
138LIST_HEAD(ioc_list);
139 /* Callback lookup table */
140static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
141 /* Protocol driver class lookup table */
142static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
143 /* Event handler lookup table */
144static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
145 /* Reset handler lookup table */
146static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
148
149static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
150
151/*
152 * Driver Callback Index's
153 */
154static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
155static u8 last_drv_idx;
156
157/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
158/*
159 * Forward protos...
160 */
161static irqreturn_t mpt_interrupt(int irq, void *bus_id);
162static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
163static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
164 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
165 int sleepFlag);
166static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
167static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
168static void mpt_adapter_disable(MPT_ADAPTER *ioc);
169static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
170
171static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
172static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
173static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
174static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
175static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
176static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
177static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
178static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
179static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
180static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
181static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
182static int PrimeIocFifos(MPT_ADAPTER *ioc);
183static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
184static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186static int GetLanConfigPages(MPT_ADAPTER *ioc);
187static int GetIoUnitPage2(MPT_ADAPTER *ioc);
188int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
189static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
190static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
191static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
192static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
193static void mpt_timer_expired(unsigned long data);
194static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
195static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
196static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
197static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
198static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
199
200#ifdef CONFIG_PROC_FS
201static int procmpt_summary_read(char *buf, char **start, off_t offset,
202 int request, int *eof, void *data);
203static int procmpt_version_read(char *buf, char **start, off_t offset,
204 int request, int *eof, void *data);
205static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
206 int request, int *eof, void *data);
207#endif
208static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
209
210//int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
211static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
212static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
213static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
214static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
215static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
216static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
217static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
218
219/* module entry point */
220static int __init fusion_init (void);
221static void __exit fusion_exit (void);
222
223#define CHIPREG_READ32(addr) readl_relaxed(addr)
224#define CHIPREG_READ32_dmasync(addr) readl(addr)
225#define CHIPREG_WRITE32(addr,val) writel(val, addr)
226#define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
227#define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
228
229static void
230pci_disable_io_access(struct pci_dev *pdev)
231{
232 u16 command_reg;
233
234 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
235 command_reg &= ~1;
236 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
237}
238
239static void
240pci_enable_io_access(struct pci_dev *pdev)
241{
242 u16 command_reg;
243
244 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
245 command_reg |= 1;
246 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
247}
248
249static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
250{
251 int ret = param_set_int(val, kp);
252 MPT_ADAPTER *ioc;
253
254 if (ret)
255 return ret;
256
257 list_for_each_entry(ioc, &ioc_list, list)
258 ioc->debug_level = mpt_debug_level;
259 return 0;
260}
261
262/**
263 * mpt_get_cb_idx - obtain cb_idx for registered driver
264 * @dclass: class driver enum
265 *
266 * Returns cb_idx, or zero means it wasn't found
267 **/
268static u8
269mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
270{
271 u8 cb_idx;
272
273 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
274 if (MptDriverClass[cb_idx] == dclass)
275 return cb_idx;
276 return 0;
277}
278
279/**
280 * mpt_fault_reset_work - work performed on workq after ioc fault
281 * @work: input argument, used to derive ioc
282 *
283**/
284static void
285mpt_fault_reset_work(struct work_struct *work)
286{
287 MPT_ADAPTER *ioc =
288 container_of(work, MPT_ADAPTER, fault_reset_work.work);
289 u32 ioc_raw_state;
290 int rc;
291 unsigned long flags;
292
293 if (ioc->diagPending || !ioc->active)
294 goto out;
295
296 ioc_raw_state = mpt_GetIocState(ioc, 0);
297 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
298 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
299 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
300 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
301 ioc->name, __func__);
302 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
303 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
304 __func__, (rc == 0) ? "success" : "failed");
305 ioc_raw_state = mpt_GetIocState(ioc, 0);
306 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
307 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
308 "reset (%04xh)\n", ioc->name, ioc_raw_state &
309 MPI_DOORBELL_DATA_MASK);
310 }
311
312 out:
313 /*
314 * Take turns polling alternate controller
315 */
316 if (ioc->alt_ioc)
317 ioc = ioc->alt_ioc;
318
319 /* rearm the timer */
320 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
321 if (ioc->reset_work_q)
322 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
323 msecs_to_jiffies(MPT_POLLING_INTERVAL));
324 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
325}
326
327
328/*
329 * Process turbo (context) reply...
330 */
331static void
332mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
333{
334 MPT_FRAME_HDR *mf = NULL;
335 MPT_FRAME_HDR *mr = NULL;
336 u16 req_idx = 0;
337 u8 cb_idx;
338
339 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
340 ioc->name, pa));
341
342 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
343 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
344 req_idx = pa & 0x0000FFFF;
345 cb_idx = (pa & 0x00FF0000) >> 16;
346 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
347 break;
348 case MPI_CONTEXT_REPLY_TYPE_LAN:
349 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
350 /*
351 * Blind set of mf to NULL here was fatal
352 * after lan_reply says "freeme"
353 * Fix sort of combined with an optimization here;
354 * added explicit check for case where lan_reply
355 * was just returning 1 and doing nothing else.
356 * For this case skip the callback, but set up
357 * proper mf value first here:-)
358 */
359 if ((pa & 0x58000000) == 0x58000000) {
360 req_idx = pa & 0x0000FFFF;
361 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
362 mpt_free_msg_frame(ioc, mf);
363 mb();
364 return;
365 break;
366 }
367 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
368 break;
369 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
370 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
371 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
372 break;
373 default:
374 cb_idx = 0;
375 BUG();
376 }
377
378 /* Check for (valid) IO callback! */
379 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
380 MptCallbacks[cb_idx] == NULL) {
381 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
382 __func__, ioc->name, cb_idx);
383 goto out;
384 }
385
386 if (MptCallbacks[cb_idx](ioc, mf, mr))
387 mpt_free_msg_frame(ioc, mf);
388 out:
389 mb();
390}
391
392static void
393mpt_reply(MPT_ADAPTER *ioc, u32 pa)
394{
395 MPT_FRAME_HDR *mf;
396 MPT_FRAME_HDR *mr;
397 u16 req_idx;
398 u8 cb_idx;
399 int freeme;
400
401 u32 reply_dma_low;
402 u16 ioc_stat;
403
404 /* non-TURBO reply! Hmmm, something may be up...
405 * Newest turbo reply mechanism; get address
406 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
407 */
408
409 /* Map DMA address of reply header to cpu address.
410 * pa is 32 bits - but the dma address may be 32 or 64 bits
411 * get offset based only only the low addresses
412 */
413
414 reply_dma_low = (pa <<= 1);
415 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
416 (reply_dma_low - ioc->reply_frames_low_dma));
417
418 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
419 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
420 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
421
422 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
423 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
424 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
425
426 /* Check/log IOC log info
427 */
428 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
429 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
430 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
431 if (ioc->bus_type == FC)
432 mpt_fc_log_info(ioc, log_info);
433 else if (ioc->bus_type == SPI)
434 mpt_spi_log_info(ioc, log_info);
435 else if (ioc->bus_type == SAS)
436 mpt_sas_log_info(ioc, log_info);
437 }
438
439 if (ioc_stat & MPI_IOCSTATUS_MASK)
440 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
441
442 /* Check for (valid) IO callback! */
443 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
444 MptCallbacks[cb_idx] == NULL) {
445 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
446 __func__, ioc->name, cb_idx);
447 freeme = 0;
448 goto out;
449 }
450
451 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
452
453 out:
454 /* Flush (non-TURBO) reply with a WRITE! */
455 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
456
457 if (freeme)
458 mpt_free_msg_frame(ioc, mf);
459 mb();
460}
461
462/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
463/**
464 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
465 * @irq: irq number (not used)
466 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
467 *
468 * This routine is registered via the request_irq() kernel API call,
469 * and handles all interrupts generated from a specific MPT adapter
470 * (also referred to as a IO Controller or IOC).
471 * This routine must clear the interrupt from the adapter and does
472 * so by reading the reply FIFO. Multiple replies may be processed
473 * per single call to this routine.
474 *
475 * This routine handles register-level access of the adapter but
476 * dispatches (calls) a protocol-specific callback routine to handle
477 * the protocol-specific details of the MPT request completion.
478 */
479static irqreturn_t
480mpt_interrupt(int irq, void *bus_id)
481{
482 MPT_ADAPTER *ioc = bus_id;
483 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
484
485 if (pa == 0xFFFFFFFF)
486 return IRQ_NONE;
487
488 /*
489 * Drain the reply FIFO!
490 */
491 do {
492 if (pa & MPI_ADDRESS_REPLY_A_BIT)
493 mpt_reply(ioc, pa);
494 else
495 mpt_turbo_reply(ioc, pa);
496 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
497 } while (pa != 0xFFFFFFFF);
498
499 return IRQ_HANDLED;
500}
501
502/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
503/**
504 * mpt_base_reply - MPT base driver's callback routine
505 * @ioc: Pointer to MPT_ADAPTER structure
506 * @mf: Pointer to original MPT request frame
507 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
508 *
509 * MPT base driver's callback routine; all base driver
510 * "internal" request/reply processing is routed here.
511 * Currently used for EventNotification and EventAck handling.
512 *
513 * Returns 1 indicating original alloc'd request frame ptr
514 * should be freed, or 0 if it shouldn't.
515 */
516static int
517mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
518{
519 int freereq = 1;
520 u8 func;
521
522 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
523#ifdef CONFIG_FUSION_LOGGING
524 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
525 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
526 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
527 ioc->name, mf));
528 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
529 }
530#endif
531
532 func = reply->u.hdr.Function;
533 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
534 ioc->name, func));
535
536 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
537 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
538 int evHandlers = 0;
539 int results;
540
541 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
542 if (results != evHandlers) {
543 /* CHECKME! Any special handling needed here? */
544 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
545 ioc->name, evHandlers, results));
546 }
547
548 /*
549 * Hmmm... It seems that EventNotificationReply is an exception
550 * to the rule of one reply per request.
551 */
552 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
553 freereq = 0;
554 } else {
555 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
556 ioc->name, pEvReply));
557 }
558
559#ifdef CONFIG_PROC_FS
560// LogEvent(ioc, pEvReply);
561#endif
562
563 } else if (func == MPI_FUNCTION_EVENT_ACK) {
564 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
565 ioc->name));
566 } else if (func == MPI_FUNCTION_CONFIG) {
567 CONFIGPARMS *pCfg;
568 unsigned long flags;
569
570 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
571 ioc->name, mf, reply));
572
573 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
574
575 if (pCfg) {
576 /* disable timer and remove from linked list */
577 del_timer(&pCfg->timer);
578
579 spin_lock_irqsave(&ioc->FreeQlock, flags);
580 list_del(&pCfg->linkage);
581 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
582
583 /*
584 * If IOC Status is SUCCESS, save the header
585 * and set the status code to GOOD.
586 */
587 pCfg->status = MPT_CONFIG_ERROR;
588 if (reply) {
589 ConfigReply_t *pReply = (ConfigReply_t *)reply;
590 u16 status;
591
592 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
593 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
594 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
595
596 pCfg->status = status;
597 if (status == MPI_IOCSTATUS_SUCCESS) {
598 if ((pReply->Header.PageType &
599 MPI_CONFIG_PAGETYPE_MASK) ==
600 MPI_CONFIG_PAGETYPE_EXTENDED) {
601 pCfg->cfghdr.ehdr->ExtPageLength =
602 le16_to_cpu(pReply->ExtPageLength);
603 pCfg->cfghdr.ehdr->ExtPageType =
604 pReply->ExtPageType;
605 }
606 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
607
608 /* If this is a regular header, save PageLength. */
609 /* LMP Do this better so not using a reserved field! */
610 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
611 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
612 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
613 }
614 }
615
616 /*
617 * Wake up the original calling thread
618 */
619 pCfg->wait_done = 1;
620 wake_up(&mpt_waitq);
621 }
622 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
623 /* we should be always getting a reply frame */
624 memcpy(ioc->persist_reply_frame, reply,
625 min(MPT_DEFAULT_FRAME_SIZE,
626 4*reply->u.reply.MsgLength));
627 del_timer(&ioc->persist_timer);
628 ioc->persist_wait_done = 1;
629 wake_up(&mpt_waitq);
630 } else {
631 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
632 ioc->name, func);
633 }
634
635 /*
636 * Conditionally tell caller to free the original
637 * EventNotification/EventAck/unexpected request frame!
638 */
639 return freereq;
640}
641
642/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
643/**
644 * mpt_register - Register protocol-specific main callback handler.
645 * @cbfunc: callback function pointer
646 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
647 *
648 * This routine is called by a protocol-specific driver (SCSI host,
649 * LAN, SCSI target) to register its reply callback routine. Each
650 * protocol-specific driver must do this before it will be able to
651 * use any IOC resources, such as obtaining request frames.
652 *
653 * NOTES: The SCSI protocol driver currently calls this routine thrice
654 * in order to register separate callbacks; one for "normal" SCSI IO;
655 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
656 *
657 * Returns u8 valued "handle" in the range (and S.O.D. order)
658 * {N,...,7,6,5,...,1} if successful.
659 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
660 * considered an error by the caller.
661 */
662u8
663mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
664{
665 u8 cb_idx;
666 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
667
668 /*
669 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
670 * (slot/handle 0 is reserved!)
671 */
672 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
673 if (MptCallbacks[cb_idx] == NULL) {
674 MptCallbacks[cb_idx] = cbfunc;
675 MptDriverClass[cb_idx] = dclass;
676 MptEvHandlers[cb_idx] = NULL;
677 last_drv_idx = cb_idx;
678 break;
679 }
680 }
681
682 return last_drv_idx;
683}
684
685/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
686/**
687 * mpt_deregister - Deregister a protocol drivers resources.
688 * @cb_idx: previously registered callback handle
689 *
690 * Each protocol-specific driver should call this routine when its
691 * module is unloaded.
692 */
693void
694mpt_deregister(u8 cb_idx)
695{
696 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
697 MptCallbacks[cb_idx] = NULL;
698 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
699 MptEvHandlers[cb_idx] = NULL;
700
701 last_drv_idx++;
702 }
703}
704
705/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
706/**
707 * mpt_event_register - Register protocol-specific event callback handler.
708 * @cb_idx: previously registered (via mpt_register) callback handle
709 * @ev_cbfunc: callback function
710 *
711 * This routine can be called by one or more protocol-specific drivers
712 * if/when they choose to be notified of MPT events.
713 *
714 * Returns 0 for success.
715 */
716int
717mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
718{
719 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
720 return -1;
721
722 MptEvHandlers[cb_idx] = ev_cbfunc;
723 return 0;
724}
725
726/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
727/**
728 * mpt_event_deregister - Deregister protocol-specific event callback handler
729 * @cb_idx: previously registered callback handle
730 *
731 * Each protocol-specific driver should call this routine
732 * when it does not (or can no longer) handle events,
733 * or when its module is unloaded.
734 */
735void
736mpt_event_deregister(u8 cb_idx)
737{
738 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
739 return;
740
741 MptEvHandlers[cb_idx] = NULL;
742}
743
744/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
745/**
746 * mpt_reset_register - Register protocol-specific IOC reset handler.
747 * @cb_idx: previously registered (via mpt_register) callback handle
748 * @reset_func: reset function
749 *
750 * This routine can be called by one or more protocol-specific drivers
751 * if/when they choose to be notified of IOC resets.
752 *
753 * Returns 0 for success.
754 */
755int
756mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
757{
758 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
759 return -1;
760
761 MptResetHandlers[cb_idx] = reset_func;
762 return 0;
763}
764
765/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
766/**
767 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
768 * @cb_idx: previously registered callback handle
769 *
770 * Each protocol-specific driver should call this routine
771 * when it does not (or can no longer) handle IOC reset handling,
772 * or when its module is unloaded.
773 */
774void
775mpt_reset_deregister(u8 cb_idx)
776{
777 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
778 return;
779
780 MptResetHandlers[cb_idx] = NULL;
781}
782
783/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
784/**
785 * mpt_device_driver_register - Register device driver hooks
786 * @dd_cbfunc: driver callbacks struct
787 * @cb_idx: MPT protocol driver index
788 */
789int
790mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
791{
792 MPT_ADAPTER *ioc;
793 const struct pci_device_id *id;
794
795 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
796 return -EINVAL;
797
798 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
799
800 /* call per pci device probe entry point */
801 list_for_each_entry(ioc, &ioc_list, list) {
802 id = ioc->pcidev->driver ?
803 ioc->pcidev->driver->id_table : NULL;
804 if (dd_cbfunc->probe)
805 dd_cbfunc->probe(ioc->pcidev, id);
806 }
807
808 return 0;
809}
810
811/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
812/**
813 * mpt_device_driver_deregister - DeRegister device driver hooks
814 * @cb_idx: MPT protocol driver index
815 */
816void
817mpt_device_driver_deregister(u8 cb_idx)
818{
819 struct mpt_pci_driver *dd_cbfunc;
820 MPT_ADAPTER *ioc;
821
822 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
823 return;
824
825 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
826
827 list_for_each_entry(ioc, &ioc_list, list) {
828 if (dd_cbfunc->remove)
829 dd_cbfunc->remove(ioc->pcidev);
830 }
831
832 MptDeviceDriverHandlers[cb_idx] = NULL;
833}
834
835
836/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
837/**
838 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
839 * @cb_idx: Handle of registered MPT protocol driver
840 * @ioc: Pointer to MPT adapter structure
841 *
842 * Obtain an MPT request frame from the pool (of 1024) that are
843 * allocated per MPT adapter.
844 *
845 * Returns pointer to a MPT request frame or %NULL if none are available
846 * or IOC is not active.
847 */
848MPT_FRAME_HDR*
849mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
850{
851 MPT_FRAME_HDR *mf;
852 unsigned long flags;
853 u16 req_idx; /* Request index */
854
855 /* validate handle and ioc identifier */
856
857#ifdef MFCNT
858 if (!ioc->active)
859 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
860 "returning NULL!\n", ioc->name);
861#endif
862
863 /* If interrupts are not attached, do not return a request frame */
864 if (!ioc->active)
865 return NULL;
866
867 spin_lock_irqsave(&ioc->FreeQlock, flags);
868 if (!list_empty(&ioc->FreeQ)) {
869 int req_offset;
870
871 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
872 u.frame.linkage.list);
873 list_del(&mf->u.frame.linkage.list);
874 mf->u.frame.linkage.arg1 = 0;
875 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
876 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
877 /* u16! */
878 req_idx = req_offset / ioc->req_sz;
879 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
880 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
881 /* Default, will be changed if necessary in SG generation */
882 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
883#ifdef MFCNT
884 ioc->mfcnt++;
885#endif
886 }
887 else
888 mf = NULL;
889 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
890
891#ifdef MFCNT
892 if (mf == NULL)
893 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
894 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
895 ioc->req_depth);
896 mfcounter++;
897 if (mfcounter == PRINT_MF_COUNT)
898 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
899 ioc->mfcnt, ioc->req_depth);
900#endif
901
902 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
903 ioc->name, cb_idx, ioc->id, mf));
904 return mf;
905}
906
907/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
908/**
909 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
910 * @cb_idx: Handle of registered MPT protocol driver
911 * @ioc: Pointer to MPT adapter structure
912 * @mf: Pointer to MPT request frame
913 *
914 * This routine posts an MPT request frame to the request post FIFO of a
915 * specific MPT adapter.
916 */
917void
918mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
919{
920 u32 mf_dma_addr;
921 int req_offset;
922 u16 req_idx; /* Request index */
923
924 /* ensure values are reset properly! */
925 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
926 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
927 /* u16! */
928 req_idx = req_offset / ioc->req_sz;
929 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
930 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
931
932 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
933
934 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
935 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
936 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
937 ioc->RequestNB[req_idx]));
938 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
939}
940
941/**
942 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
943 * @cb_idx: Handle of registered MPT protocol driver
944 * @ioc: Pointer to MPT adapter structure
945 * @mf: Pointer to MPT request frame
946 *
947 * Send a protocol-specific MPT request frame to an IOC using
948 * hi-priority request queue.
949 *
950 * This routine posts an MPT request frame to the request post FIFO of a
951 * specific MPT adapter.
952 **/
953void
954mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
955{
956 u32 mf_dma_addr;
957 int req_offset;
958 u16 req_idx; /* Request index */
959
960 /* ensure values are reset properly! */
961 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
962 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
963 req_idx = req_offset / ioc->req_sz;
964 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
965 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
966
967 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
968
969 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
970 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
971 ioc->name, mf_dma_addr, req_idx));
972 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
973}
974
975/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
976/**
977 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
978 * @ioc: Pointer to MPT adapter structure
979 * @mf: Pointer to MPT request frame
980 *
981 * This routine places a MPT request frame back on the MPT adapter's
982 * FreeQ.
983 */
984void
985mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
986{
987 unsigned long flags;
988
989 /* Put Request back on FreeQ! */
990 spin_lock_irqsave(&ioc->FreeQlock, flags);
991 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
992 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
993#ifdef MFCNT
994 ioc->mfcnt--;
995#endif
996 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
997}
998
999/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1000/**
1001 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1002 * @pAddr: virtual address for SGE
1003 * @flagslength: SGE flags and data transfer length
1004 * @dma_addr: Physical address
1005 *
1006 * This routine places a MPT request frame back on the MPT adapter's
1007 * FreeQ.
1008 */
1009static void
1010mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1011{
1012 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1013 pSge->FlagsLength = cpu_to_le32(flagslength);
1014 pSge->Address = cpu_to_le32(dma_addr);
1015}
1016
1017/**
1018 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1019 * @pAddr: virtual address for SGE
1020 * @flagslength: SGE flags and data transfer length
1021 * @dma_addr: Physical address
1022 *
1023 * This routine places a MPT request frame back on the MPT adapter's
1024 * FreeQ.
1025 **/
1026static void
1027mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1028{
1029 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1030 pSge->Address.Low = cpu_to_le32
1031 (lower_32_bits((unsigned long)(dma_addr)));
1032 pSge->Address.High = cpu_to_le32
1033 (upper_32_bits((unsigned long)dma_addr));
1034 pSge->FlagsLength = cpu_to_le32
1035 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1036}
1037
1038/**
1039 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr
1040 * (1078 workaround).
1041 * @pAddr: virtual address for SGE
1042 * @flagslength: SGE flags and data transfer length
1043 * @dma_addr: Physical address
1044 *
1045 * This routine places a MPT request frame back on the MPT adapter's
1046 * FreeQ.
1047 **/
1048static void
1049mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1050{
1051 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1052 u32 tmp;
1053
1054 pSge->Address.Low = cpu_to_le32
1055 (lower_32_bits((unsigned long)(dma_addr)));
1056 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1057
1058 /*
1059 * 1078 errata workaround for the 36GB limitation
1060 */
1061 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1062 flagslength |=
1063 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1064 tmp |= (1<<31);
1065 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1066 printk(KERN_DEBUG "1078 P0M2 addressing for "
1067 "addr = 0x%llx len = %d\n",
1068 (unsigned long long)dma_addr,
1069 MPI_SGE_LENGTH(flagslength));
1070 }
1071
1072 pSge->Address.High = cpu_to_le32(tmp);
1073 pSge->FlagsLength = cpu_to_le32(
1074 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1075}
1076
1077/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1078/**
1079 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1080 * @pAddr: virtual address for SGE
1081 * @next: nextChainOffset value (u32's)
1082 * @length: length of next SGL segment
1083 * @dma_addr: Physical address
1084 *
1085 */
1086static void
1087mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1088{
1089 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1090 pChain->Length = cpu_to_le16(length);
1091 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1092 pChain->NextChainOffset = next;
1093 pChain->Address = cpu_to_le32(dma_addr);
1094}
1095
1096/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1097/**
1098 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1099 * @pAddr: virtual address for SGE
1100 * @next: nextChainOffset value (u32's)
1101 * @length: length of next SGL segment
1102 * @dma_addr: Physical address
1103 *
1104 */
1105static void
1106mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1107{
1108 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1109 u32 tmp = dma_addr & 0xFFFFFFFF;
1110
1111 pChain->Length = cpu_to_le16(length);
1112 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1113 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1114
1115 pChain->NextChainOffset = next;
1116
1117 pChain->Address.Low = cpu_to_le32(tmp);
1118 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1119 pChain->Address.High = cpu_to_le32(tmp);
1120}
1121
1122/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1123/**
1124 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1125 * @cb_idx: Handle of registered MPT protocol driver
1126 * @ioc: Pointer to MPT adapter structure
1127 * @reqBytes: Size of the request in bytes
1128 * @req: Pointer to MPT request frame
1129 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1130 *
1131 * This routine is used exclusively to send MptScsiTaskMgmt
1132 * requests since they are required to be sent via doorbell handshake.
1133 *
1134 * NOTE: It is the callers responsibility to byte-swap fields in the
1135 * request which are greater than 1 byte in size.
1136 *
1137 * Returns 0 for success, non-zero for failure.
1138 */
1139int
1140mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1141{
1142 int r = 0;
1143 u8 *req_as_bytes;
1144 int ii;
1145
1146 /* State is known to be good upon entering
1147 * this function so issue the bus reset
1148 * request.
1149 */
1150
1151 /*
1152 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1153 * setting cb_idx/req_idx. But ONLY if this request
1154 * is in proper (pre-alloc'd) request buffer range...
1155 */
1156 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1157 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1158 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1159 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1160 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1161 }
1162
1163 /* Make sure there are no doorbells */
1164 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1165
1166 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1167 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1168 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1169
1170 /* Wait for IOC doorbell int */
1171 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1172 return ii;
1173 }
1174
1175 /* Read doorbell and check for active bit */
1176 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1177 return -5;
1178
1179 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1180 ioc->name, ii));
1181
1182 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1183
1184 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1185 return -2;
1186 }
1187
1188 /* Send request via doorbell handshake */
1189 req_as_bytes = (u8 *) req;
1190 for (ii = 0; ii < reqBytes/4; ii++) {
1191 u32 word;
1192
1193 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1194 (req_as_bytes[(ii*4) + 1] << 8) |
1195 (req_as_bytes[(ii*4) + 2] << 16) |
1196 (req_as_bytes[(ii*4) + 3] << 24));
1197 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1198 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1199 r = -3;
1200 break;
1201 }
1202 }
1203
1204 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1205 r = 0;
1206 else
1207 r = -4;
1208
1209 /* Make sure there are no doorbells */
1210 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1211
1212 return r;
1213}
1214
1215/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1216/**
1217 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1218 * @ioc: Pointer to MPT adapter structure
1219 * @access_control_value: define bits below
1220 * @sleepFlag: Specifies whether the process can sleep
1221 *
1222 * Provides mechanism for the host driver to control the IOC's
1223 * Host Page Buffer access.
1224 *
1225 * Access Control Value - bits[15:12]
1226 * 0h Reserved
1227 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1228 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1229 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1230 *
1231 * Returns 0 for success, non-zero for failure.
1232 */
1233
1234static int
1235mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1236{
1237 int r = 0;
1238
1239 /* return if in use */
1240 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1241 & MPI_DOORBELL_ACTIVE)
1242 return -1;
1243
1244 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1245
1246 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1247 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1248 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1249 (access_control_value<<12)));
1250
1251 /* Wait for IOC to clear Doorbell Status bit */
1252 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1253 return -2;
1254 }else
1255 return 0;
1256}
1257
1258/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1259/**
1260 * mpt_host_page_alloc - allocate system memory for the fw
1261 * @ioc: Pointer to pointer to IOC adapter
1262 * @ioc_init: Pointer to ioc init config page
1263 *
1264 * If we already allocated memory in past, then resend the same pointer.
1265 * Returns 0 for success, non-zero for failure.
1266 */
1267static int
1268mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1269{
1270 char *psge;
1271 int flags_length;
1272 u32 host_page_buffer_sz=0;
1273
1274 if(!ioc->HostPageBuffer) {
1275
1276 host_page_buffer_sz =
1277 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1278
1279 if(!host_page_buffer_sz)
1280 return 0; /* fw doesn't need any host buffers */
1281
1282 /* spin till we get enough memory */
1283 while(host_page_buffer_sz > 0) {
1284
1285 if((ioc->HostPageBuffer = pci_alloc_consistent(
1286 ioc->pcidev,
1287 host_page_buffer_sz,
1288 &ioc->HostPageBuffer_dma)) != NULL) {
1289
1290 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1291 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1292 ioc->name, ioc->HostPageBuffer,
1293 (u32)ioc->HostPageBuffer_dma,
1294 host_page_buffer_sz));
1295 ioc->alloc_total += host_page_buffer_sz;
1296 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1297 break;
1298 }
1299
1300 host_page_buffer_sz -= (4*1024);
1301 }
1302 }
1303
1304 if(!ioc->HostPageBuffer) {
1305 printk(MYIOC_s_ERR_FMT
1306 "Failed to alloc memory for host_page_buffer!\n",
1307 ioc->name);
1308 return -999;
1309 }
1310
1311 psge = (char *)&ioc_init->HostPageBufferSGE;
1312 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1313 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1314 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1315 MPI_SGE_FLAGS_HOST_TO_IOC |
1316 MPI_SGE_FLAGS_END_OF_BUFFER;
1317 if (sizeof(dma_addr_t) == sizeof(u64)) {
1318 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1319 }
1320 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1321 flags_length |= ioc->HostPageBuffer_sz;
1322 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1323 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1324
1325return 0;
1326}
1327
1328/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1329/**
1330 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1331 * @iocid: IOC unique identifier (integer)
1332 * @iocpp: Pointer to pointer to IOC adapter
1333 *
1334 * Given a unique IOC identifier, set pointer to the associated MPT
1335 * adapter structure.
1336 *
1337 * Returns iocid and sets iocpp if iocid is found.
1338 * Returns -1 if iocid is not found.
1339 */
1340int
1341mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1342{
1343 MPT_ADAPTER *ioc;
1344
1345 list_for_each_entry(ioc,&ioc_list,list) {
1346 if (ioc->id == iocid) {
1347 *iocpp =ioc;
1348 return iocid;
1349 }
1350 }
1351
1352 *iocpp = NULL;
1353 return -1;
1354}
1355
1356/**
1357 * mpt_get_product_name - returns product string
1358 * @vendor: pci vendor id
1359 * @device: pci device id
1360 * @revision: pci revision id
1361 * @prod_name: string returned
1362 *
1363 * Returns product string displayed when driver loads,
1364 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1365 *
1366 **/
1367static void
1368mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1369{
1370 char *product_str = NULL;
1371
1372 if (vendor == PCI_VENDOR_ID_BROCADE) {
1373 switch (device)
1374 {
1375 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1376 switch (revision)
1377 {
1378 case 0x00:
1379 product_str = "BRE040 A0";
1380 break;
1381 case 0x01:
1382 product_str = "BRE040 A1";
1383 break;
1384 default:
1385 product_str = "BRE040";
1386 break;
1387 }
1388 break;
1389 }
1390 goto out;
1391 }
1392
1393 switch (device)
1394 {
1395 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1396 product_str = "LSIFC909 B1";
1397 break;
1398 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1399 product_str = "LSIFC919 B0";
1400 break;
1401 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1402 product_str = "LSIFC929 B0";
1403 break;
1404 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1405 if (revision < 0x80)
1406 product_str = "LSIFC919X A0";
1407 else
1408 product_str = "LSIFC919XL A1";
1409 break;
1410 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1411 if (revision < 0x80)
1412 product_str = "LSIFC929X A0";
1413 else
1414 product_str = "LSIFC929XL A1";
1415 break;
1416 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1417 product_str = "LSIFC939X A1";
1418 break;
1419 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1420 product_str = "LSIFC949X A1";
1421 break;
1422 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1423 switch (revision)
1424 {
1425 case 0x00:
1426 product_str = "LSIFC949E A0";
1427 break;
1428 case 0x01:
1429 product_str = "LSIFC949E A1";
1430 break;
1431 default:
1432 product_str = "LSIFC949E";
1433 break;
1434 }
1435 break;
1436 case MPI_MANUFACTPAGE_DEVID_53C1030:
1437 switch (revision)
1438 {
1439 case 0x00:
1440 product_str = "LSI53C1030 A0";
1441 break;
1442 case 0x01:
1443 product_str = "LSI53C1030 B0";
1444 break;
1445 case 0x03:
1446 product_str = "LSI53C1030 B1";
1447 break;
1448 case 0x07:
1449 product_str = "LSI53C1030 B2";
1450 break;
1451 case 0x08:
1452 product_str = "LSI53C1030 C0";
1453 break;
1454 case 0x80:
1455 product_str = "LSI53C1030T A0";
1456 break;
1457 case 0x83:
1458 product_str = "LSI53C1030T A2";
1459 break;
1460 case 0x87:
1461 product_str = "LSI53C1030T A3";
1462 break;
1463 case 0xc1:
1464 product_str = "LSI53C1020A A1";
1465 break;
1466 default:
1467 product_str = "LSI53C1030";
1468 break;
1469 }
1470 break;
1471 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1472 switch (revision)
1473 {
1474 case 0x03:
1475 product_str = "LSI53C1035 A2";
1476 break;
1477 case 0x04:
1478 product_str = "LSI53C1035 B0";
1479 break;
1480 default:
1481 product_str = "LSI53C1035";
1482 break;
1483 }
1484 break;
1485 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1486 switch (revision)
1487 {
1488 case 0x00:
1489 product_str = "LSISAS1064 A1";
1490 break;
1491 case 0x01:
1492 product_str = "LSISAS1064 A2";
1493 break;
1494 case 0x02:
1495 product_str = "LSISAS1064 A3";
1496 break;
1497 case 0x03:
1498 product_str = "LSISAS1064 A4";
1499 break;
1500 default:
1501 product_str = "LSISAS1064";
1502 break;
1503 }
1504 break;
1505 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1506 switch (revision)
1507 {
1508 case 0x00:
1509 product_str = "LSISAS1064E A0";
1510 break;
1511 case 0x01:
1512 product_str = "LSISAS1064E B0";
1513 break;
1514 case 0x02:
1515 product_str = "LSISAS1064E B1";
1516 break;
1517 case 0x04:
1518 product_str = "LSISAS1064E B2";
1519 break;
1520 case 0x08:
1521 product_str = "LSISAS1064E B3";
1522 break;
1523 default:
1524 product_str = "LSISAS1064E";
1525 break;
1526 }
1527 break;
1528 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1529 switch (revision)
1530 {
1531 case 0x00:
1532 product_str = "LSISAS1068 A0";
1533 break;
1534 case 0x01:
1535 product_str = "LSISAS1068 B0";
1536 break;
1537 case 0x02:
1538 product_str = "LSISAS1068 B1";
1539 break;
1540 default:
1541 product_str = "LSISAS1068";
1542 break;
1543 }
1544 break;
1545 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1546 switch (revision)
1547 {
1548 case 0x00:
1549 product_str = "LSISAS1068E A0";
1550 break;
1551 case 0x01:
1552 product_str = "LSISAS1068E B0";
1553 break;
1554 case 0x02:
1555 product_str = "LSISAS1068E B1";
1556 break;
1557 case 0x04:
1558 product_str = "LSISAS1068E B2";
1559 break;
1560 case 0x08:
1561 product_str = "LSISAS1068E B3";
1562 break;
1563 default:
1564 product_str = "LSISAS1068E";
1565 break;
1566 }
1567 break;
1568 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1569 switch (revision)
1570 {
1571 case 0x00:
1572 product_str = "LSISAS1078 A0";
1573 break;
1574 case 0x01:
1575 product_str = "LSISAS1078 B0";
1576 break;
1577 case 0x02:
1578 product_str = "LSISAS1078 C0";
1579 break;
1580 case 0x03:
1581 product_str = "LSISAS1078 C1";
1582 break;
1583 case 0x04:
1584 product_str = "LSISAS1078 C2";
1585 break;
1586 default:
1587 product_str = "LSISAS1078";
1588 break;
1589 }
1590 break;
1591 }
1592
1593 out:
1594 if (product_str)
1595 sprintf(prod_name, "%s", product_str);
1596}
1597
1598/**
1599 * mpt_mapresources - map in memory mapped io
1600 * @ioc: Pointer to pointer to IOC adapter
1601 *
1602 **/
1603static int
1604mpt_mapresources(MPT_ADAPTER *ioc)
1605{
1606 u8 __iomem *mem;
1607 int ii;
1608 unsigned long mem_phys;
1609 unsigned long port;
1610 u32 msize;
1611 u32 psize;
1612 u8 revision;
1613 int r = -ENODEV;
1614 struct pci_dev *pdev;
1615
1616 pdev = ioc->pcidev;
1617 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1618 if (pci_enable_device_mem(pdev)) {
1619 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1620 "failed\n", ioc->name);
1621 return r;
1622 }
1623 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1624 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1625 "MEM failed\n", ioc->name);
1626 return r;
1627 }
1628
1629 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1630
1631 if (sizeof(dma_addr_t) > 4) {
1632 const uint64_t required_mask = dma_get_required_mask
1633 (&pdev->dev);
1634 if (required_mask > DMA_BIT_MASK(32)
1635 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1636 && !pci_set_consistent_dma_mask(pdev,
1637 DMA_BIT_MASK(64))) {
1638 ioc->dma_mask = DMA_BIT_MASK(64);
1639 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1640 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1641 ioc->name));
1642 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1643 && !pci_set_consistent_dma_mask(pdev,
1644 DMA_BIT_MASK(32))) {
1645 ioc->dma_mask = DMA_BIT_MASK(32);
1646 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1647 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1648 ioc->name));
1649 } else {
1650 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1651 ioc->name, pci_name(pdev));
1652 return r;
1653 }
1654 } else {
1655 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1656 && !pci_set_consistent_dma_mask(pdev,
1657 DMA_BIT_MASK(32))) {
1658 ioc->dma_mask = DMA_BIT_MASK(32);
1659 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1660 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1661 ioc->name));
1662 } else {
1663 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1664 ioc->name, pci_name(pdev));
1665 return r;
1666 }
1667 }
1668
1669 mem_phys = msize = 0;
1670 port = psize = 0;
1671 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1672 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1673 if (psize)
1674 continue;
1675 /* Get I/O space! */
1676 port = pci_resource_start(pdev, ii);
1677 psize = pci_resource_len(pdev, ii);
1678 } else {
1679 if (msize)
1680 continue;
1681 /* Get memmap */
1682 mem_phys = pci_resource_start(pdev, ii);
1683 msize = pci_resource_len(pdev, ii);
1684 }
1685 }
1686 ioc->mem_size = msize;
1687
1688 mem = NULL;
1689 /* Get logical ptr for PciMem0 space */
1690 /*mem = ioremap(mem_phys, msize);*/
1691 mem = ioremap(mem_phys, msize);
1692 if (mem == NULL) {
1693 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1694 " memory!\n", ioc->name);
1695 return -EINVAL;
1696 }
1697 ioc->memmap = mem;
1698 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1699 ioc->name, mem, mem_phys));
1700
1701 ioc->mem_phys = mem_phys;
1702 ioc->chip = (SYSIF_REGS __iomem *)mem;
1703
1704 /* Save Port IO values in case we need to do downloadboot */
1705 ioc->pio_mem_phys = port;
1706 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1707
1708 return 0;
1709}
1710
1711/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1712/**
1713 * mpt_attach - Install a PCI intelligent MPT adapter.
1714 * @pdev: Pointer to pci_dev structure
1715 * @id: PCI device ID information
1716 *
1717 * This routine performs all the steps necessary to bring the IOC of
1718 * a MPT adapter to a OPERATIONAL state. This includes registering
1719 * memory regions, registering the interrupt, and allocating request
1720 * and reply memory pools.
1721 *
1722 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1723 * MPT adapter.
1724 *
1725 * Returns 0 for success, non-zero for failure.
1726 *
1727 * TODO: Add support for polled controllers
1728 */
1729int
1730mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1731{
1732 MPT_ADAPTER *ioc;
1733 u8 cb_idx;
1734 int r = -ENODEV;
1735 u8 revision;
1736 u8 pcixcmd;
1737 static int mpt_ids = 0;
1738#ifdef CONFIG_PROC_FS
1739 struct proc_dir_entry *dent, *ent;
1740#endif
1741
1742 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1743 if (ioc == NULL) {
1744 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1745 return -ENOMEM;
1746 }
1747
1748 ioc->id = mpt_ids++;
1749 sprintf(ioc->name, "ioc%d", ioc->id);
1750
1751 /*
1752 * set initial debug level
1753 * (refer to mptdebug.h)
1754 *
1755 */
1756 ioc->debug_level = mpt_debug_level;
1757 if (mpt_debug_level)
1758 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1759
1760 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1761
1762 ioc->pcidev = pdev;
1763 if (mpt_mapresources(ioc)) {
1764 kfree(ioc);
1765 return r;
1766 }
1767
1768 /*
1769 * Setting up proper handlers for scatter gather handling
1770 */
1771 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1772 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1773 ioc->add_sge = &mpt_add_sge_64bit_1078;
1774 else
1775 ioc->add_sge = &mpt_add_sge_64bit;
1776 ioc->add_chain = &mpt_add_chain_64bit;
1777 ioc->sg_addr_size = 8;
1778 } else {
1779 ioc->add_sge = &mpt_add_sge;
1780 ioc->add_chain = &mpt_add_chain;
1781 ioc->sg_addr_size = 4;
1782 }
1783 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1784
1785 ioc->alloc_total = sizeof(MPT_ADAPTER);
1786 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1787 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1788
1789 ioc->pcidev = pdev;
1790 ioc->diagPending = 0;
1791 spin_lock_init(&ioc->diagLock);
1792 spin_lock_init(&ioc->initializing_hba_lock);
1793
1794 /* Initialize the event logging.
1795 */
1796 ioc->eventTypes = 0; /* None */
1797 ioc->eventContext = 0;
1798 ioc->eventLogSize = 0;
1799 ioc->events = NULL;
1800
1801#ifdef MFCNT
1802 ioc->mfcnt = 0;
1803#endif
1804
1805 ioc->cached_fw = NULL;
1806
1807 /* Initilize SCSI Config Data structure
1808 */
1809 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1810
1811 /* Initialize the running configQ head.
1812 */
1813 INIT_LIST_HEAD(&ioc->configQ);
1814
1815 /* Initialize the fc rport list head.
1816 */
1817 INIT_LIST_HEAD(&ioc->fc_rports);
1818
1819 /* Find lookup slot. */
1820 INIT_LIST_HEAD(&ioc->list);
1821
1822
1823 /* Initialize workqueue */
1824 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1825 spin_lock_init(&ioc->fault_reset_work_lock);
1826
1827 snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name),
1828 "mpt_poll_%d", ioc->id);
1829 ioc->reset_work_q =
1830 create_singlethread_workqueue(ioc->reset_work_q_name);
1831 if (!ioc->reset_work_q) {
1832 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1833 ioc->name);
1834 pci_release_selected_regions(pdev, ioc->bars);
1835 kfree(ioc);
1836 return -ENOMEM;
1837 }
1838
1839 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1840 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1841
1842 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1843 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1844
1845 switch (pdev->device)
1846 {
1847 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1848 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1849 ioc->errata_flag_1064 = 1;
1850 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1851 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1852 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1853 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1854 ioc->bus_type = FC;
1855 break;
1856
1857 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1858 if (revision < XL_929) {
1859 /* 929X Chip Fix. Set Split transactions level
1860 * for PCIX. Set MOST bits to zero.
1861 */
1862 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1863 pcixcmd &= 0x8F;
1864 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1865 } else {
1866 /* 929XL Chip Fix. Set MMRBC to 0x08.
1867 */
1868 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1869 pcixcmd |= 0x08;
1870 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1871 }
1872 ioc->bus_type = FC;
1873 break;
1874
1875 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1876 /* 919X Chip Fix. Set Split transactions level
1877 * for PCIX. Set MOST bits to zero.
1878 */
1879 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1880 pcixcmd &= 0x8F;
1881 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1882 ioc->bus_type = FC;
1883 break;
1884
1885 case MPI_MANUFACTPAGE_DEVID_53C1030:
1886 /* 1030 Chip Fix. Disable Split transactions
1887 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1888 */
1889 if (revision < C0_1030) {
1890 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1891 pcixcmd &= 0x8F;
1892 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1893 }
1894
1895 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1896 ioc->bus_type = SPI;
1897 break;
1898
1899 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1900 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1901 ioc->errata_flag_1064 = 1;
1902
1903 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1904 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1905 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1906 ioc->bus_type = SAS;
1907 }
1908
1909
1910 switch (ioc->bus_type) {
1911
1912 case SAS:
1913 ioc->msi_enable = mpt_msi_enable_sas;
1914 break;
1915
1916 case SPI:
1917 ioc->msi_enable = mpt_msi_enable_spi;
1918 break;
1919
1920 case FC:
1921 ioc->msi_enable = mpt_msi_enable_fc;
1922 break;
1923
1924 default:
1925 ioc->msi_enable = 0;
1926 break;
1927 }
1928 if (ioc->errata_flag_1064)
1929 pci_disable_io_access(pdev);
1930
1931 spin_lock_init(&ioc->FreeQlock);
1932
1933 /* Disable all! */
1934 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1935 ioc->active = 0;
1936 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1937
1938 /* Set IOC ptr in the pcidev's driver data. */
1939 pci_set_drvdata(ioc->pcidev, ioc);
1940
1941 /* Set lookup ptr. */
1942 list_add_tail(&ioc->list, &ioc_list);
1943
1944 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1945 */
1946 mpt_detect_bound_ports(ioc, pdev);
1947
1948 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1949 CAN_SLEEP)) != 0){
1950 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1951 ioc->name, r);
1952
1953 list_del(&ioc->list);
1954 if (ioc->alt_ioc)
1955 ioc->alt_ioc->alt_ioc = NULL;
1956 iounmap(ioc->memmap);
1957 if (r != -5)
1958 pci_release_selected_regions(pdev, ioc->bars);
1959
1960 destroy_workqueue(ioc->reset_work_q);
1961 ioc->reset_work_q = NULL;
1962
1963 kfree(ioc);
1964 pci_set_drvdata(pdev, NULL);
1965 return r;
1966 }
1967
1968 /* call per device driver probe entry point */
1969 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1970 if(MptDeviceDriverHandlers[cb_idx] &&
1971 MptDeviceDriverHandlers[cb_idx]->probe) {
1972 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1973 }
1974 }
1975
1976#ifdef CONFIG_PROC_FS
1977 /*
1978 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1979 */
1980 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1981 if (dent) {
1982 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1983 if (ent) {
1984 ent->read_proc = procmpt_iocinfo_read;
1985 ent->data = ioc;
1986 }
1987 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1988 if (ent) {
1989 ent->read_proc = procmpt_summary_read;
1990 ent->data = ioc;
1991 }
1992 }
1993#endif
1994
1995 if (!ioc->alt_ioc)
1996 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1997 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1998
1999 return 0;
2000}
2001
2002/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2003/**
2004 * mpt_detach - Remove a PCI intelligent MPT adapter.
2005 * @pdev: Pointer to pci_dev structure
2006 */
2007
2008void
2009mpt_detach(struct pci_dev *pdev)
2010{
2011 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2012 char pname[32];
2013 u8 cb_idx;
2014 unsigned long flags;
2015 struct workqueue_struct *wq;
2016
2017 /*
2018 * Stop polling ioc for fault condition
2019 */
2020 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
2021 wq = ioc->reset_work_q;
2022 ioc->reset_work_q = NULL;
2023 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
2024 cancel_delayed_work(&ioc->fault_reset_work);
2025 destroy_workqueue(wq);
2026
2027
2028 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2029 remove_proc_entry(pname, NULL);
2030 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2031 remove_proc_entry(pname, NULL);
2032 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2033 remove_proc_entry(pname, NULL);
2034
2035 /* call per device driver remove entry point */
2036 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2037 if(MptDeviceDriverHandlers[cb_idx] &&
2038 MptDeviceDriverHandlers[cb_idx]->remove) {
2039 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2040 }
2041 }
2042
2043 /* Disable interrupts! */
2044 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2045
2046 ioc->active = 0;
2047 synchronize_irq(pdev->irq);
2048
2049 /* Clear any lingering interrupt */
2050 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2051
2052 CHIPREG_READ32(&ioc->chip->IntStatus);
2053
2054 mpt_adapter_dispose(ioc);
2055
2056 pci_set_drvdata(pdev, NULL);
2057}
2058
2059/**************************************************************************
2060 * Power Management
2061 */
2062#ifdef CONFIG_PM
2063/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2064/**
2065 * mpt_suspend - Fusion MPT base driver suspend routine.
2066 * @pdev: Pointer to pci_dev structure
2067 * @state: new state to enter
2068 */
2069int
2070mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2071{
2072 u32 device_state;
2073 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2074
2075 device_state = pci_choose_state(pdev, state);
2076 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2077 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2078 device_state);
2079
2080 /* put ioc into READY_STATE */
2081 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2082 printk(MYIOC_s_ERR_FMT
2083 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2084 }
2085
2086 /* disable interrupts */
2087 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2088 ioc->active = 0;
2089
2090 /* Clear any lingering interrupt */
2091 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2092
2093 free_irq(ioc->pci_irq, ioc);
2094 if (ioc->msi_enable)
2095 pci_disable_msi(ioc->pcidev);
2096 ioc->pci_irq = -1;
2097 pci_save_state(pdev);
2098 pci_disable_device(pdev);
2099 pci_release_selected_regions(pdev, ioc->bars);
2100 pci_set_power_state(pdev, device_state);
2101 return 0;
2102}
2103
2104/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2105/**
2106 * mpt_resume - Fusion MPT base driver resume routine.
2107 * @pdev: Pointer to pci_dev structure
2108 */
2109int
2110mpt_resume(struct pci_dev *pdev)
2111{
2112 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2113 u32 device_state = pdev->current_state;
2114 int recovery_state;
2115 int err;
2116
2117 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2118 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2119 device_state);
2120
2121 pci_set_power_state(pdev, PCI_D0);
2122 pci_enable_wake(pdev, PCI_D0, 0);
2123 pci_restore_state(pdev);
2124 ioc->pcidev = pdev;
2125 err = mpt_mapresources(ioc);
2126 if (err)
2127 return err;
2128
2129 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2130 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2131 ioc->add_sge = &mpt_add_sge_64bit_1078;
2132 else
2133 ioc->add_sge = &mpt_add_sge_64bit;
2134 ioc->add_chain = &mpt_add_chain_64bit;
2135 ioc->sg_addr_size = 8;
2136 } else {
2137
2138 ioc->add_sge = &mpt_add_sge;
2139 ioc->add_chain = &mpt_add_chain;
2140 ioc->sg_addr_size = 4;
2141 }
2142 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2143
2144 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2145 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2146 CHIPREG_READ32(&ioc->chip->Doorbell));
2147
2148 /*
2149 * Errata workaround for SAS pci express:
2150 * Upon returning to the D0 state, the contents of the doorbell will be
2151 * stale data, and this will incorrectly signal to the host driver that
2152 * the firmware is ready to process mpt commands. The workaround is
2153 * to issue a diagnostic reset.
2154 */
2155 if (ioc->bus_type == SAS && (pdev->device ==
2156 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2157 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2158 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2159 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2160 ioc->name);
2161 goto out;
2162 }
2163 }
2164
2165 /* bring ioc to operational state */
2166 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2167 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2168 CAN_SLEEP);
2169 if (recovery_state != 0)
2170 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2171 "error:[%x]\n", ioc->name, recovery_state);
2172 else
2173 printk(MYIOC_s_INFO_FMT
2174 "pci-resume: success\n", ioc->name);
2175 out:
2176 return 0;
2177
2178}
2179#endif
2180
2181static int
2182mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2183{
2184 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2185 ioc->bus_type != SPI) ||
2186 (MptDriverClass[index] == MPTFC_DRIVER &&
2187 ioc->bus_type != FC) ||
2188 (MptDriverClass[index] == MPTSAS_DRIVER &&
2189 ioc->bus_type != SAS))
2190 /* make sure we only call the relevant reset handler
2191 * for the bus */
2192 return 0;
2193 return (MptResetHandlers[index])(ioc, reset_phase);
2194}
2195
2196/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2197/**
2198 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2199 * @ioc: Pointer to MPT adapter structure
2200 * @reason: Event word / reason
2201 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2202 *
2203 * This routine performs all the steps necessary to bring the IOC
2204 * to a OPERATIONAL state.
2205 *
2206 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2207 * MPT adapter.
2208 *
2209 * Returns:
2210 * 0 for success
2211 * -1 if failed to get board READY
2212 * -2 if READY but IOCFacts Failed
2213 * -3 if READY but PrimeIOCFifos Failed
2214 * -4 if READY but IOCInit Failed
2215 * -5 if failed to enable_device and/or request_selected_regions
2216 * -6 if failed to upload firmware
2217 */
2218static int
2219mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2220{
2221 int hard_reset_done = 0;
2222 int alt_ioc_ready = 0;
2223 int hard;
2224 int rc=0;
2225 int ii;
2226 u8 cb_idx;
2227 int handlers;
2228 int ret = 0;
2229 int reset_alt_ioc_active = 0;
2230 int irq_allocated = 0;
2231 u8 *a;
2232
2233 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2234 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2235
2236 /* Disable reply interrupts (also blocks FreeQ) */
2237 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2238 ioc->active = 0;
2239
2240 if (ioc->alt_ioc) {
2241 if (ioc->alt_ioc->active)
2242 reset_alt_ioc_active = 1;
2243
2244 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
2245 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
2246 ioc->alt_ioc->active = 0;
2247 }
2248
2249 hard = 1;
2250 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2251 hard = 0;
2252
2253 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2254 if (hard_reset_done == -4) {
2255 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2256 ioc->name);
2257
2258 if (reset_alt_ioc_active && ioc->alt_ioc) {
2259 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2260 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2261 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2262 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2263 ioc->alt_ioc->active = 1;
2264 }
2265
2266 } else {
2267 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
2268 }
2269 return -1;
2270 }
2271
2272 /* hard_reset_done = 0 if a soft reset was performed
2273 * and 1 if a hard reset was performed.
2274 */
2275 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2276 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2277 alt_ioc_ready = 1;
2278 else
2279 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
2280 }
2281
2282 for (ii=0; ii<5; ii++) {
2283 /* Get IOC facts! Allow 5 retries */
2284 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2285 break;
2286 }
2287
2288
2289 if (ii == 5) {
2290 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2291 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2292 ret = -2;
2293 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2294 MptDisplayIocCapabilities(ioc);
2295 }
2296
2297 if (alt_ioc_ready) {
2298 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2299 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2300 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
2301 /* Retry - alt IOC was initialized once
2302 */
2303 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2304 }
2305 if (rc) {
2306 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2307 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2308 alt_ioc_ready = 0;
2309 reset_alt_ioc_active = 0;
2310 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2311 MptDisplayIocCapabilities(ioc->alt_ioc);
2312 }
2313 }
2314
2315 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2316 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2317 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2318 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2319 IORESOURCE_IO);
2320 if (pci_enable_device(ioc->pcidev))
2321 return -5;
2322 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2323 "mpt"))
2324 return -5;
2325 }
2326
2327 /*
2328 * Device is reset now. It must have de-asserted the interrupt line
2329 * (if it was asserted) and it should be safe to register for the
2330 * interrupt now.
2331 */
2332 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2333 ioc->pci_irq = -1;
2334 if (ioc->pcidev->irq) {
2335 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2336 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2337 ioc->name);
2338 else
2339 ioc->msi_enable = 0;
2340 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2341 IRQF_SHARED, ioc->name, ioc);
2342 if (rc < 0) {
2343 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2344 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2345 if (ioc->msi_enable)
2346 pci_disable_msi(ioc->pcidev);
2347 return -EBUSY;
2348 }
2349 irq_allocated = 1;
2350 ioc->pci_irq = ioc->pcidev->irq;
2351 pci_set_master(ioc->pcidev); /* ?? */
2352 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2353 "%d\n", ioc->name, ioc->pcidev->irq));
2354 }
2355 }
2356
2357 /* Prime reply & request queues!
2358 * (mucho alloc's) Must be done prior to
2359 * init as upper addresses are needed for init.
2360 * If fails, continue with alt-ioc processing
2361 */
2362 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2363 ret = -3;
2364
2365 /* May need to check/upload firmware & data here!
2366 * If fails, continue with alt-ioc processing
2367 */
2368 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2369 ret = -4;
2370// NEW!
2371 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2372 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2373 ioc->alt_ioc->name, rc);
2374 alt_ioc_ready = 0;
2375 reset_alt_ioc_active = 0;
2376 }
2377
2378 if (alt_ioc_ready) {
2379 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2380 alt_ioc_ready = 0;
2381 reset_alt_ioc_active = 0;
2382 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2383 ioc->alt_ioc->name, rc);
2384 }
2385 }
2386
2387 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2388 if (ioc->upload_fw) {
2389 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2390 "firmware upload required!\n", ioc->name));
2391
2392 /* Controller is not operational, cannot do upload
2393 */
2394 if (ret == 0) {
2395 rc = mpt_do_upload(ioc, sleepFlag);
2396 if (rc == 0) {
2397 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2398 /*
2399 * Maintain only one pointer to FW memory
2400 * so there will not be two attempt to
2401 * downloadboot onboard dual function
2402 * chips (mpt_adapter_disable,
2403 * mpt_diag_reset)
2404 */
2405 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2406 "mpt_upload: alt_%s has cached_fw=%p \n",
2407 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2408 ioc->cached_fw = NULL;
2409 }
2410 } else {
2411 printk(MYIOC_s_WARN_FMT
2412 "firmware upload failure!\n", ioc->name);
2413 ret = -6;
2414 }
2415 }
2416 }
2417 }
2418
2419 if (ret == 0) {
2420 /* Enable! (reply interrupt) */
2421 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2422 ioc->active = 1;
2423 }
2424
2425 if (reset_alt_ioc_active && ioc->alt_ioc) {
2426 /* (re)Enable alt-IOC! (reply interrupt) */
2427 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2428 ioc->alt_ioc->name));
2429 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2430 ioc->alt_ioc->active = 1;
2431 }
2432
2433 /* Enable MPT base driver management of EventNotification
2434 * and EventAck handling.
2435 */
2436 if ((ret == 0) && (!ioc->facts.EventState))
2437 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2438
2439 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2440 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2441
2442 /* Add additional "reason" check before call to GetLanConfigPages
2443 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2444 * recursive scenario; GetLanConfigPages times out, timer expired
2445 * routine calls HardResetHandler, which calls into here again,
2446 * and we try GetLanConfigPages again...
2447 */
2448 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2449
2450 /*
2451 * Initalize link list for inactive raid volumes.
2452 */
2453 mutex_init(&ioc->raid_data.inactive_list_mutex);
2454 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2455
2456 if (ioc->bus_type == SAS) {
2457
2458 /* clear persistency table */
2459 if(ioc->facts.IOCExceptions &
2460 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2461 ret = mptbase_sas_persist_operation(ioc,
2462 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2463 if(ret != 0)
2464 goto out;
2465 }
2466
2467 /* Find IM volumes
2468 */
2469 mpt_findImVolumes(ioc);
2470
2471 } else if (ioc->bus_type == FC) {
2472 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2473 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2474 /*
2475 * Pre-fetch the ports LAN MAC address!
2476 * (LANPage1_t stuff)
2477 */
2478 (void) GetLanConfigPages(ioc);
2479 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2480 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2481 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2482 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2483
2484 }
2485 } else {
2486 /* Get NVRAM and adapter maximums from SPP 0 and 2
2487 */
2488 mpt_GetScsiPortSettings(ioc, 0);
2489
2490 /* Get version and length of SDP 1
2491 */
2492 mpt_readScsiDevicePageHeaders(ioc, 0);
2493
2494 /* Find IM volumes
2495 */
2496 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2497 mpt_findImVolumes(ioc);
2498
2499 /* Check, and possibly reset, the coalescing value
2500 */
2501 mpt_read_ioc_pg_1(ioc);
2502
2503 mpt_read_ioc_pg_4(ioc);
2504 }
2505
2506 GetIoUnitPage2(ioc);
2507 mpt_get_manufacturing_pg_0(ioc);
2508 }
2509
2510 /*
2511 * Call each currently registered protocol IOC reset handler
2512 * with post-reset indication.
2513 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2514 * MptResetHandlers[] registered yet.
2515 */
2516 if (hard_reset_done) {
2517 rc = handlers = 0;
2518 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2519 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2520 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2521 "Calling IOC post_reset handler #%d\n",
2522 ioc->name, cb_idx));
2523 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2524 handlers++;
2525 }
2526
2527 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2528 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2529 "Calling IOC post_reset handler #%d\n",
2530 ioc->alt_ioc->name, cb_idx));
2531 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2532 handlers++;
2533 }
2534 }
2535 /* FIXME? Examine results here? */
2536 }
2537
2538 out:
2539 if ((ret != 0) && irq_allocated) {
2540 free_irq(ioc->pci_irq, ioc);
2541 if (ioc->msi_enable)
2542 pci_disable_msi(ioc->pcidev);
2543 }
2544 return ret;
2545}
2546
2547/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2548/**
2549 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2550 * @ioc: Pointer to MPT adapter structure
2551 * @pdev: Pointer to (struct pci_dev) structure
2552 *
2553 * Search for PCI bus/dev_function which matches
2554 * PCI bus/dev_function (+/-1) for newly discovered 929,
2555 * 929X, 1030 or 1035.
2556 *
2557 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2558 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2559 */
2560static void
2561mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2562{
2563 struct pci_dev *peer=NULL;
2564 unsigned int slot = PCI_SLOT(pdev->devfn);
2565 unsigned int func = PCI_FUNC(pdev->devfn);
2566 MPT_ADAPTER *ioc_srch;
2567
2568 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2569 " searching for devfn match on %x or %x\n",
2570 ioc->name, pci_name(pdev), pdev->bus->number,
2571 pdev->devfn, func-1, func+1));
2572
2573 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2574 if (!peer) {
2575 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2576 if (!peer)
2577 return;
2578 }
2579
2580 list_for_each_entry(ioc_srch, &ioc_list, list) {
2581 struct pci_dev *_pcidev = ioc_srch->pcidev;
2582 if (_pcidev == peer) {
2583 /* Paranoia checks */
2584 if (ioc->alt_ioc != NULL) {
2585 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2586 ioc->name, ioc->alt_ioc->name);
2587 break;
2588 } else if (ioc_srch->alt_ioc != NULL) {
2589 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2590 ioc_srch->name, ioc_srch->alt_ioc->name);
2591 break;
2592 }
2593 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2594 ioc->name, ioc_srch->name));
2595 ioc_srch->alt_ioc = ioc;
2596 ioc->alt_ioc = ioc_srch;
2597 }
2598 }
2599 pci_dev_put(peer);
2600}
2601
2602/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2603/**
2604 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2605 * @ioc: Pointer to MPT adapter structure
2606 */
2607static void
2608mpt_adapter_disable(MPT_ADAPTER *ioc)
2609{
2610 int sz;
2611 int ret;
2612
2613 if (ioc->cached_fw != NULL) {
2614 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2615 "adapter\n", __func__, ioc->name));
2616 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2617 ioc->cached_fw, CAN_SLEEP)) < 0) {
2618 printk(MYIOC_s_WARN_FMT
2619 ": firmware downloadboot failure (%d)!\n",
2620 ioc->name, ret);
2621 }
2622 }
2623
2624 /* Disable adapter interrupts! */
2625 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2626 ioc->active = 0;
2627 /* Clear any lingering interrupt */
2628 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2629
2630 if (ioc->alloc != NULL) {
2631 sz = ioc->alloc_sz;
2632 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2633 ioc->name, ioc->alloc, ioc->alloc_sz));
2634 pci_free_consistent(ioc->pcidev, sz,
2635 ioc->alloc, ioc->alloc_dma);
2636 ioc->reply_frames = NULL;
2637 ioc->req_frames = NULL;
2638 ioc->alloc = NULL;
2639 ioc->alloc_total -= sz;
2640 }
2641
2642 if (ioc->sense_buf_pool != NULL) {
2643 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2644 pci_free_consistent(ioc->pcidev, sz,
2645 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2646 ioc->sense_buf_pool = NULL;
2647 ioc->alloc_total -= sz;
2648 }
2649
2650 if (ioc->events != NULL){
2651 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2652 kfree(ioc->events);
2653 ioc->events = NULL;
2654 ioc->alloc_total -= sz;
2655 }
2656
2657 mpt_free_fw_memory(ioc);
2658
2659 kfree(ioc->spi_data.nvram);
2660 mpt_inactive_raid_list_free(ioc);
2661 kfree(ioc->raid_data.pIocPg2);
2662 kfree(ioc->raid_data.pIocPg3);
2663 ioc->spi_data.nvram = NULL;
2664 ioc->raid_data.pIocPg3 = NULL;
2665
2666 if (ioc->spi_data.pIocPg4 != NULL) {
2667 sz = ioc->spi_data.IocPg4Sz;
2668 pci_free_consistent(ioc->pcidev, sz,
2669 ioc->spi_data.pIocPg4,
2670 ioc->spi_data.IocPg4_dma);
2671 ioc->spi_data.pIocPg4 = NULL;
2672 ioc->alloc_total -= sz;
2673 }
2674
2675 if (ioc->ReqToChain != NULL) {
2676 kfree(ioc->ReqToChain);
2677 kfree(ioc->RequestNB);
2678 ioc->ReqToChain = NULL;
2679 }
2680
2681 kfree(ioc->ChainToChain);
2682 ioc->ChainToChain = NULL;
2683
2684 if (ioc->HostPageBuffer != NULL) {
2685 if((ret = mpt_host_page_access_control(ioc,
2686 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2687 printk(MYIOC_s_ERR_FMT
2688 "host page buffers free failed (%d)!\n",
2689 ioc->name, ret);
2690 }
2691 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2692 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2693 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2694 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2695 ioc->HostPageBuffer = NULL;
2696 ioc->HostPageBuffer_sz = 0;
2697 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2698 }
2699}
2700
2701/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2702/**
2703 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2704 * @ioc: Pointer to MPT adapter structure
2705 *
2706 * This routine unregisters h/w resources and frees all alloc'd memory
2707 * associated with a MPT adapter structure.
2708 */
2709static void
2710mpt_adapter_dispose(MPT_ADAPTER *ioc)
2711{
2712 int sz_first, sz_last;
2713
2714 if (ioc == NULL)
2715 return;
2716
2717 sz_first = ioc->alloc_total;
2718
2719 mpt_adapter_disable(ioc);
2720
2721 if (ioc->pci_irq != -1) {
2722 free_irq(ioc->pci_irq, ioc);
2723 if (ioc->msi_enable)
2724 pci_disable_msi(ioc->pcidev);
2725 ioc->pci_irq = -1;
2726 }
2727
2728 if (ioc->memmap != NULL) {
2729 iounmap(ioc->memmap);
2730 ioc->memmap = NULL;
2731 }
2732
2733 pci_disable_device(ioc->pcidev);
2734 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2735
2736#if defined(CONFIG_MTRR) && 0
2737 if (ioc->mtrr_reg > 0) {
2738 mtrr_del(ioc->mtrr_reg, 0, 0);
2739 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2740 }
2741#endif
2742
2743 /* Zap the adapter lookup ptr! */
2744 list_del(&ioc->list);
2745
2746 sz_last = ioc->alloc_total;
2747 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2748 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2749
2750 if (ioc->alt_ioc)
2751 ioc->alt_ioc->alt_ioc = NULL;
2752
2753 kfree(ioc);
2754}
2755
2756/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2757/**
2758 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2759 * @ioc: Pointer to MPT adapter structure
2760 */
2761static void
2762MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2763{
2764 int i = 0;
2765
2766 printk(KERN_INFO "%s: ", ioc->name);
2767 if (ioc->prod_name)
2768 printk("%s: ", ioc->prod_name);
2769 printk("Capabilities={");
2770
2771 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2772 printk("Initiator");
2773 i++;
2774 }
2775
2776 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2777 printk("%sTarget", i ? "," : "");
2778 i++;
2779 }
2780
2781 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2782 printk("%sLAN", i ? "," : "");
2783 i++;
2784 }
2785
2786#if 0
2787 /*
2788 * This would probably evoke more questions than it's worth
2789 */
2790 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2791 printk("%sLogBusAddr", i ? "," : "");
2792 i++;
2793 }
2794#endif
2795
2796 printk("}\n");
2797}
2798
2799/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2800/**
2801 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2802 * @ioc: Pointer to MPT_ADAPTER structure
2803 * @force: Force hard KickStart of IOC
2804 * @sleepFlag: Specifies whether the process can sleep
2805 *
2806 * Returns:
2807 * 1 - DIAG reset and READY
2808 * 0 - READY initially OR soft reset and READY
2809 * -1 - Any failure on KickStart
2810 * -2 - Msg Unit Reset Failed
2811 * -3 - IO Unit Reset Failed
2812 * -4 - IOC owned by a PEER
2813 */
2814static int
2815MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2816{
2817 u32 ioc_state;
2818 int statefault = 0;
2819 int cntdn;
2820 int hard_reset_done = 0;
2821 int r;
2822 int ii;
2823 int whoinit;
2824
2825 /* Get current [raw] IOC state */
2826 ioc_state = mpt_GetIocState(ioc, 0);
2827 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2828
2829 /*
2830 * Check to see if IOC got left/stuck in doorbell handshake
2831 * grip of death. If so, hard reset the IOC.
2832 */
2833 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2834 statefault = 1;
2835 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2836 ioc->name);
2837 }
2838
2839 /* Is it already READY? */
2840 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2841 return 0;
2842
2843 /*
2844 * Check to see if IOC is in FAULT state.
2845 */
2846 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2847 statefault = 2;
2848 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2849 ioc->name);
2850 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2851 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2852 }
2853
2854 /*
2855 * Hmmm... Did it get left operational?
2856 */
2857 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2858 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2859 ioc->name));
2860
2861 /* Check WhoInit.
2862 * If PCI Peer, exit.
2863 * Else, if no fault conditions are present, issue a MessageUnitReset
2864 * Else, fall through to KickStart case
2865 */
2866 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2867 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2868 "whoinit 0x%x statefault %d force %d\n",
2869 ioc->name, whoinit, statefault, force));
2870 if (whoinit == MPI_WHOINIT_PCI_PEER)
2871 return -4;
2872 else {
2873 if ((statefault == 0 ) && (force == 0)) {
2874 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2875 return 0;
2876 }
2877 statefault = 3;
2878 }
2879 }
2880
2881 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2882 if (hard_reset_done < 0)
2883 return -1;
2884
2885 /*
2886 * Loop here waiting for IOC to come READY.
2887 */
2888 ii = 0;
2889 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2890
2891 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2892 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2893 /*
2894 * BIOS or previous driver load left IOC in OP state.
2895 * Reset messaging FIFOs.
2896 */
2897 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2898 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2899 return -2;
2900 }
2901 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2902 /*
2903 * Something is wrong. Try to get IOC back
2904 * to a known state.
2905 */
2906 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2907 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2908 return -3;
2909 }
2910 }
2911
2912 ii++; cntdn--;
2913 if (!cntdn) {
2914 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2915 ioc->name, (int)((ii+5)/HZ));
2916 return -ETIME;
2917 }
2918
2919 if (sleepFlag == CAN_SLEEP) {
2920 msleep(1);
2921 } else {
2922 mdelay (1); /* 1 msec delay */
2923 }
2924
2925 }
2926
2927 if (statefault < 3) {
2928 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2929 ioc->name,
2930 statefault==1 ? "stuck handshake" : "IOC FAULT");
2931 }
2932
2933 return hard_reset_done;
2934}
2935
2936/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2937/**
2938 * mpt_GetIocState - Get the current state of a MPT adapter.
2939 * @ioc: Pointer to MPT_ADAPTER structure
2940 * @cooked: Request raw or cooked IOC state
2941 *
2942 * Returns all IOC Doorbell register bits if cooked==0, else just the
2943 * Doorbell bits in MPI_IOC_STATE_MASK.
2944 */
2945u32
2946mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2947{
2948 u32 s, sc;
2949
2950 /* Get! */
2951 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2952 sc = s & MPI_IOC_STATE_MASK;
2953
2954 /* Save! */
2955 ioc->last_state = sc;
2956
2957 return cooked ? sc : s;
2958}
2959
2960/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2961/**
2962 * GetIocFacts - Send IOCFacts request to MPT adapter.
2963 * @ioc: Pointer to MPT_ADAPTER structure
2964 * @sleepFlag: Specifies whether the process can sleep
2965 * @reason: If recovery, only update facts.
2966 *
2967 * Returns 0 for success, non-zero for failure.
2968 */
2969static int
2970GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2971{
2972 IOCFacts_t get_facts;
2973 IOCFactsReply_t *facts;
2974 int r;
2975 int req_sz;
2976 int reply_sz;
2977 int sz;
2978 u32 status, vv;
2979 u8 shiftFactor=1;
2980
2981 /* IOC *must* NOT be in RESET state! */
2982 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2983 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2984 ioc->name, ioc->last_state );
2985 return -44;
2986 }
2987
2988 facts = &ioc->facts;
2989
2990 /* Destination (reply area)... */
2991 reply_sz = sizeof(*facts);
2992 memset(facts, 0, reply_sz);
2993
2994 /* Request area (get_facts on the stack right now!) */
2995 req_sz = sizeof(get_facts);
2996 memset(&get_facts, 0, req_sz);
2997
2998 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2999 /* Assert: All other get_facts fields are zero! */
3000
3001 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3002 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3003 ioc->name, req_sz, reply_sz));
3004
3005 /* No non-zero fields in the get_facts request are greater than
3006 * 1 byte in size, so we can just fire it off as is.
3007 */
3008 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3009 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3010 if (r != 0)
3011 return r;
3012
3013 /*
3014 * Now byte swap (GRRR) the necessary fields before any further
3015 * inspection of reply contents.
3016 *
3017 * But need to do some sanity checks on MsgLength (byte) field
3018 * to make sure we don't zero IOC's req_sz!
3019 */
3020 /* Did we get a valid reply? */
3021 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3022 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3023 /*
3024 * If not been here, done that, save off first WhoInit value
3025 */
3026 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3027 ioc->FirstWhoInit = facts->WhoInit;
3028 }
3029
3030 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3031 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3032 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3033 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3034 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3035 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3036 /* CHECKME! IOCStatus, IOCLogInfo */
3037
3038 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3039 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3040
3041 /*
3042 * FC f/w version changed between 1.1 and 1.2
3043 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3044 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3045 */
3046 if (facts->MsgVersion < 0x0102) {
3047 /*
3048 * Handle old FC f/w style, convert to new...
3049 */
3050 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3051 facts->FWVersion.Word =
3052 ((oldv<<12) & 0xFF000000) |
3053 ((oldv<<8) & 0x000FFF00);
3054 } else
3055 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3056
3057 facts->ProductID = le16_to_cpu(facts->ProductID);
3058 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3059 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3060 ioc->ir_firmware = 1;
3061 facts->CurrentHostMfaHighAddr =
3062 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3063 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3064 facts->CurrentSenseBufferHighAddr =
3065 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3066 facts->CurReplyFrameSize =
3067 le16_to_cpu(facts->CurReplyFrameSize);
3068 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3069
3070 /*
3071 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3072 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3073 * to 14 in MPI-1.01.0x.
3074 */
3075 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3076 facts->MsgVersion > 0x0100) {
3077 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3078 }
3079
3080 sz = facts->FWImageSize;
3081 if ( sz & 0x01 )
3082 sz += 1;
3083 if ( sz & 0x02 )
3084 sz += 2;
3085 facts->FWImageSize = sz;
3086
3087 if (!facts->RequestFrameSize) {
3088 /* Something is wrong! */
3089 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3090 ioc->name);
3091 return -55;
3092 }
3093
3094 r = sz = facts->BlockSize;
3095 vv = ((63 / (sz * 4)) + 1) & 0x03;
3096 ioc->NB_for_64_byte_frame = vv;
3097 while ( sz )
3098 {
3099 shiftFactor++;
3100 sz = sz >> 1;
3101 }
3102 ioc->NBShiftFactor = shiftFactor;
3103 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3104 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3105 ioc->name, vv, shiftFactor, r));
3106
3107 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3108 /*
3109 * Set values for this IOC's request & reply frame sizes,
3110 * and request & reply queue depths...
3111 */
3112 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3113 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3114 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3115 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3116
3117 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3118 ioc->name, ioc->reply_sz, ioc->reply_depth));
3119 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3120 ioc->name, ioc->req_sz, ioc->req_depth));
3121
3122 /* Get port facts! */
3123 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3124 return r;
3125 }
3126 } else {
3127 printk(MYIOC_s_ERR_FMT
3128 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3129 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3130 RequestFrameSize)/sizeof(u32)));
3131 return -66;
3132 }
3133
3134 return 0;
3135}
3136
3137/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3138/**
3139 * GetPortFacts - Send PortFacts request to MPT adapter.
3140 * @ioc: Pointer to MPT_ADAPTER structure
3141 * @portnum: Port number
3142 * @sleepFlag: Specifies whether the process can sleep
3143 *
3144 * Returns 0 for success, non-zero for failure.
3145 */
3146static int
3147GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3148{
3149 PortFacts_t get_pfacts;
3150 PortFactsReply_t *pfacts;
3151 int ii;
3152 int req_sz;
3153 int reply_sz;
3154 int max_id;
3155
3156 /* IOC *must* NOT be in RESET state! */
3157 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3158 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3159 ioc->name, ioc->last_state );
3160 return -4;
3161 }
3162
3163 pfacts = &ioc->pfacts[portnum];
3164
3165 /* Destination (reply area)... */
3166 reply_sz = sizeof(*pfacts);
3167 memset(pfacts, 0, reply_sz);
3168
3169 /* Request area (get_pfacts on the stack right now!) */
3170 req_sz = sizeof(get_pfacts);
3171 memset(&get_pfacts, 0, req_sz);
3172
3173 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3174 get_pfacts.PortNumber = portnum;
3175 /* Assert: All other get_pfacts fields are zero! */
3176
3177 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3178 ioc->name, portnum));
3179
3180 /* No non-zero fields in the get_pfacts request are greater than
3181 * 1 byte in size, so we can just fire it off as is.
3182 */
3183 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3184 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3185 if (ii != 0)
3186 return ii;
3187
3188 /* Did we get a valid reply? */
3189
3190 /* Now byte swap the necessary fields in the response. */
3191 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3192 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3193 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3194 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3195 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3196 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3197 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3198 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3199 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3200
3201 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3202 pfacts->MaxDevices;
3203 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3204 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3205
3206 /*
3207 * Place all the devices on channels
3208 *
3209 * (for debuging)
3210 */
3211 if (mpt_channel_mapping) {
3212 ioc->devices_per_bus = 1;
3213 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3214 }
3215
3216 return 0;
3217}
3218
3219/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3220/**
3221 * SendIocInit - Send IOCInit request to MPT adapter.
3222 * @ioc: Pointer to MPT_ADAPTER structure
3223 * @sleepFlag: Specifies whether the process can sleep
3224 *
3225 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3226 *
3227 * Returns 0 for success, non-zero for failure.
3228 */
3229static int
3230SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3231{
3232 IOCInit_t ioc_init;
3233 MPIDefaultReply_t init_reply;
3234 u32 state;
3235 int r;
3236 int count;
3237 int cntdn;
3238
3239 memset(&ioc_init, 0, sizeof(ioc_init));
3240 memset(&init_reply, 0, sizeof(init_reply));
3241
3242 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3243 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3244
3245 /* If we are in a recovery mode and we uploaded the FW image,
3246 * then this pointer is not NULL. Skip the upload a second time.
3247 * Set this flag if cached_fw set for either IOC.
3248 */
3249 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3250 ioc->upload_fw = 1;
3251 else
3252 ioc->upload_fw = 0;
3253 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3254 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3255
3256 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3257 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3258 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3259 ioc->name, ioc->facts.MsgVersion));
3260 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3261 // set MsgVersion and HeaderVersion host driver was built with
3262 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3263 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3264
3265 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3266 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3267 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3268 return -99;
3269 }
3270 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3271
3272 if (sizeof(dma_addr_t) == sizeof(u64)) {
3273 /* Save the upper 32-bits of the request
3274 * (reply) and sense buffers.
3275 */
3276 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3277 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3278 } else {
3279 /* Force 32-bit addressing */
3280 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3281 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3282 }
3283
3284 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3285 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3286 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3287 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3288
3289 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3290 ioc->name, &ioc_init));
3291
3292 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3293 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3294 if (r != 0) {
3295 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3296 return r;
3297 }
3298
3299 /* No need to byte swap the multibyte fields in the reply
3300 * since we don't even look at its contents.
3301 */
3302
3303 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3304 ioc->name, &ioc_init));
3305
3306 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3307 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3308 return r;
3309 }
3310
3311 /* YIKES! SUPER IMPORTANT!!!
3312 * Poll IocState until _OPERATIONAL while IOC is doing
3313 * LoopInit and TargetDiscovery!
3314 */
3315 count = 0;
3316 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3317 state = mpt_GetIocState(ioc, 1);
3318 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3319 if (sleepFlag == CAN_SLEEP) {
3320 msleep(1);
3321 } else {
3322 mdelay(1);
3323 }
3324
3325 if (!cntdn) {
3326 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3327 ioc->name, (int)((count+5)/HZ));
3328 return -9;
3329 }
3330
3331 state = mpt_GetIocState(ioc, 1);
3332 count++;
3333 }
3334 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3335 ioc->name, count));
3336
3337 ioc->aen_event_read_flag=0;
3338 return r;
3339}
3340
3341/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3342/**
3343 * SendPortEnable - Send PortEnable request to MPT adapter port.
3344 * @ioc: Pointer to MPT_ADAPTER structure
3345 * @portnum: Port number to enable
3346 * @sleepFlag: Specifies whether the process can sleep
3347 *
3348 * Send PortEnable to bring IOC to OPERATIONAL state.
3349 *
3350 * Returns 0 for success, non-zero for failure.
3351 */
3352static int
3353SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3354{
3355 PortEnable_t port_enable;
3356 MPIDefaultReply_t reply_buf;
3357 int rc;
3358 int req_sz;
3359 int reply_sz;
3360
3361 /* Destination... */
3362 reply_sz = sizeof(MPIDefaultReply_t);
3363 memset(&reply_buf, 0, reply_sz);
3364
3365 req_sz = sizeof(PortEnable_t);
3366 memset(&port_enable, 0, req_sz);
3367
3368 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3369 port_enable.PortNumber = portnum;
3370/* port_enable.ChainOffset = 0; */
3371/* port_enable.MsgFlags = 0; */
3372/* port_enable.MsgContext = 0; */
3373
3374 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3375 ioc->name, portnum, &port_enable));
3376
3377 /* RAID FW may take a long time to enable
3378 */
3379 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3380 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3381 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3382 300 /*seconds*/, sleepFlag);
3383 } else {
3384 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3385 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3386 30 /*seconds*/, sleepFlag);
3387 }
3388 return rc;
3389}
3390
3391/**
3392 * mpt_alloc_fw_memory - allocate firmware memory
3393 * @ioc: Pointer to MPT_ADAPTER structure
3394 * @size: total FW bytes
3395 *
3396 * If memory has already been allocated, the same (cached) value
3397 * is returned.
3398 *
3399 * Return 0 if successfull, or non-zero for failure
3400 **/
3401int
3402mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3403{
3404 int rc;
3405
3406 if (ioc->cached_fw) {
3407 rc = 0; /* use already allocated memory */
3408 goto out;
3409 }
3410 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3411 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3412 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3413 rc = 0;
3414 goto out;
3415 }
3416 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3417 if (!ioc->cached_fw) {
3418 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3419 ioc->name);
3420 rc = -1;
3421 } else {
3422 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3423 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3424 ioc->alloc_total += size;
3425 rc = 0;
3426 }
3427 out:
3428 return rc;
3429}
3430
3431/**
3432 * mpt_free_fw_memory - free firmware memory
3433 * @ioc: Pointer to MPT_ADAPTER structure
3434 *
3435 * If alt_img is NULL, delete from ioc structure.
3436 * Else, delete a secondary image in same format.
3437 **/
3438void
3439mpt_free_fw_memory(MPT_ADAPTER *ioc)
3440{
3441 int sz;
3442
3443 if (!ioc->cached_fw)
3444 return;
3445
3446 sz = ioc->facts.FWImageSize;
3447 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3448 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3449 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3450 ioc->alloc_total -= sz;
3451 ioc->cached_fw = NULL;
3452}
3453
3454/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3455/**
3456 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3457 * @ioc: Pointer to MPT_ADAPTER structure
3458 * @sleepFlag: Specifies whether the process can sleep
3459 *
3460 * Returns 0 for success, >0 for handshake failure
3461 * <0 for fw upload failure.
3462 *
3463 * Remark: If bound IOC and a successful FWUpload was performed
3464 * on the bound IOC, the second image is discarded
3465 * and memory is free'd. Both channels must upload to prevent
3466 * IOC from running in degraded mode.
3467 */
3468static int
3469mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3470{
3471 u8 reply[sizeof(FWUploadReply_t)];
3472 FWUpload_t *prequest;
3473 FWUploadReply_t *preply;
3474 FWUploadTCSGE_t *ptcsge;
3475 u32 flagsLength;
3476 int ii, sz, reply_sz;
3477 int cmdStatus;
3478 int request_size;
3479 /* If the image size is 0, we are done.
3480 */
3481 if ((sz = ioc->facts.FWImageSize) == 0)
3482 return 0;
3483
3484 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3485 return -ENOMEM;
3486
3487 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3488 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3489
3490 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3491 kzalloc(ioc->req_sz, GFP_KERNEL);
3492 if (!prequest) {
3493 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3494 "while allocating memory \n", ioc->name));
3495 mpt_free_fw_memory(ioc);
3496 return -ENOMEM;
3497 }
3498
3499 preply = (FWUploadReply_t *)&reply;
3500
3501 reply_sz = sizeof(reply);
3502 memset(preply, 0, reply_sz);
3503
3504 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3505 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3506
3507 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3508 ptcsge->DetailsLength = 12;
3509 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3510 ptcsge->ImageSize = cpu_to_le32(sz);
3511 ptcsge++;
3512
3513 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3514 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3515 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3516 ioc->SGE_size;
3517 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3518 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3519 ioc->facts.FWImageSize, request_size));
3520 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3521
3522 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3523 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3524
3525 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3526
3527 cmdStatus = -EFAULT;
3528 if (ii == 0) {
3529 /* Handshake transfer was complete and successful.
3530 * Check the Reply Frame.
3531 */
3532 int status, transfer_sz;
3533 status = le16_to_cpu(preply->IOCStatus);
3534 if (status == MPI_IOCSTATUS_SUCCESS) {
3535 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3536 if (transfer_sz == sz)
3537 cmdStatus = 0;
3538 }
3539 }
3540 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3541 ioc->name, cmdStatus));
3542
3543
3544 if (cmdStatus) {
3545
3546 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3547 ioc->name));
3548 mpt_free_fw_memory(ioc);
3549 }
3550 kfree(prequest);
3551
3552 return cmdStatus;
3553}
3554
3555/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3556/**
3557 * mpt_downloadboot - DownloadBoot code
3558 * @ioc: Pointer to MPT_ADAPTER structure
3559 * @pFwHeader: Pointer to firmware header info
3560 * @sleepFlag: Specifies whether the process can sleep
3561 *
3562 * FwDownloadBoot requires Programmed IO access.
3563 *
3564 * Returns 0 for success
3565 * -1 FW Image size is 0
3566 * -2 No valid cached_fw Pointer
3567 * <0 for fw upload failure.
3568 */
3569static int
3570mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3571{
3572 MpiExtImageHeader_t *pExtImage;
3573 u32 fwSize;
3574 u32 diag0val;
3575 int count;
3576 u32 *ptrFw;
3577 u32 diagRwData;
3578 u32 nextImage;
3579 u32 load_addr;
3580 u32 ioc_state=0;
3581
3582 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3583 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3584
3585 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3586 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3587 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3588 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3589 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3590 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3591
3592 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3593
3594 /* wait 1 msec */
3595 if (sleepFlag == CAN_SLEEP) {
3596 msleep(1);
3597 } else {
3598 mdelay (1);
3599 }
3600
3601 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3602 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3603
3604 for (count = 0; count < 30; count ++) {
3605 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3606 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3607 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3608 ioc->name, count));
3609 break;
3610 }
3611 /* wait .1 sec */
3612 if (sleepFlag == CAN_SLEEP) {
3613 msleep (100);
3614 } else {
3615 mdelay (100);
3616 }
3617 }
3618
3619 if ( count == 30 ) {
3620 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3621 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3622 ioc->name, diag0val));
3623 return -3;
3624 }
3625
3626 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3627 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3628 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3629 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3630 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3631 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3632
3633 /* Set the DiagRwEn and Disable ARM bits */
3634 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3635
3636 fwSize = (pFwHeader->ImageSize + 3)/4;
3637 ptrFw = (u32 *) pFwHeader;
3638
3639 /* Write the LoadStartAddress to the DiagRw Address Register
3640 * using Programmed IO
3641 */
3642 if (ioc->errata_flag_1064)
3643 pci_enable_io_access(ioc->pcidev);
3644
3645 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3646 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3647 ioc->name, pFwHeader->LoadStartAddress));
3648
3649 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3650 ioc->name, fwSize*4, ptrFw));
3651 while (fwSize--) {
3652 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3653 }
3654
3655 nextImage = pFwHeader->NextImageHeaderOffset;
3656 while (nextImage) {
3657 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3658
3659 load_addr = pExtImage->LoadStartAddress;
3660
3661 fwSize = (pExtImage->ImageSize + 3) >> 2;
3662 ptrFw = (u32 *)pExtImage;
3663
3664 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3665 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3666 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3667
3668 while (fwSize--) {
3669 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3670 }
3671 nextImage = pExtImage->NextImageHeaderOffset;
3672 }
3673
3674 /* Write the IopResetVectorRegAddr */
3675 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3676 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3677
3678 /* Write the IopResetVectorValue */
3679 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3680 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3681
3682 /* Clear the internal flash bad bit - autoincrementing register,
3683 * so must do two writes.
3684 */
3685 if (ioc->bus_type == SPI) {
3686 /*
3687 * 1030 and 1035 H/W errata, workaround to access
3688 * the ClearFlashBadSignatureBit
3689 */
3690 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3691 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3692 diagRwData |= 0x40000000;
3693 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3694 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3695
3696 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3697 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3698 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3699 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3700
3701 /* wait 1 msec */
3702 if (sleepFlag == CAN_SLEEP) {
3703 msleep (1);
3704 } else {
3705 mdelay (1);
3706 }
3707 }
3708
3709 if (ioc->errata_flag_1064)
3710 pci_disable_io_access(ioc->pcidev);
3711
3712 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3713 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3714 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3715 ioc->name, diag0val));
3716 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3717 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3718 ioc->name, diag0val));
3719 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3720
3721 /* Write 0xFF to reset the sequencer */
3722 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3723
3724 if (ioc->bus_type == SAS) {
3725 ioc_state = mpt_GetIocState(ioc, 0);
3726 if ( (GetIocFacts(ioc, sleepFlag,
3727 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3728 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3729 ioc->name, ioc_state));
3730 return -EFAULT;
3731 }
3732 }
3733
3734 for (count=0; count<HZ*20; count++) {
3735 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3736 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3737 "downloadboot successful! (count=%d) IocState=%x\n",
3738 ioc->name, count, ioc_state));
3739 if (ioc->bus_type == SAS) {
3740 return 0;
3741 }
3742 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3743 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3744 "downloadboot: SendIocInit failed\n",
3745 ioc->name));
3746 return -EFAULT;
3747 }
3748 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3749 "downloadboot: SendIocInit successful\n",
3750 ioc->name));
3751 return 0;
3752 }
3753 if (sleepFlag == CAN_SLEEP) {
3754 msleep (10);
3755 } else {
3756 mdelay (10);
3757 }
3758 }
3759 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3760 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3761 return -EFAULT;
3762}
3763
3764/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3765/**
3766 * KickStart - Perform hard reset of MPT adapter.
3767 * @ioc: Pointer to MPT_ADAPTER structure
3768 * @force: Force hard reset
3769 * @sleepFlag: Specifies whether the process can sleep
3770 *
3771 * This routine places MPT adapter in diagnostic mode via the
3772 * WriteSequence register, and then performs a hard reset of adapter
3773 * via the Diagnostic register.
3774 *
3775 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3776 * or NO_SLEEP (interrupt thread, use mdelay)
3777 * force - 1 if doorbell active, board fault state
3778 * board operational, IOC_RECOVERY or
3779 * IOC_BRINGUP and there is an alt_ioc.
3780 * 0 else
3781 *
3782 * Returns:
3783 * 1 - hard reset, READY
3784 * 0 - no reset due to History bit, READY
3785 * -1 - no reset due to History bit but not READY
3786 * OR reset but failed to come READY
3787 * -2 - no reset, could not enter DIAG mode
3788 * -3 - reset but bad FW bit
3789 */
3790static int
3791KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3792{
3793 int hard_reset_done = 0;
3794 u32 ioc_state=0;
3795 int cnt,cntdn;
3796
3797 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3798 if (ioc->bus_type == SPI) {
3799 /* Always issue a Msg Unit Reset first. This will clear some
3800 * SCSI bus hang conditions.
3801 */
3802 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3803
3804 if (sleepFlag == CAN_SLEEP) {
3805 msleep (1000);
3806 } else {
3807 mdelay (1000);
3808 }
3809 }
3810
3811 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3812 if (hard_reset_done < 0)
3813 return hard_reset_done;
3814
3815 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3816 ioc->name));
3817
3818 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3819 for (cnt=0; cnt<cntdn; cnt++) {
3820 ioc_state = mpt_GetIocState(ioc, 1);
3821 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3822 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3823 ioc->name, cnt));
3824 return hard_reset_done;
3825 }
3826 if (sleepFlag == CAN_SLEEP) {
3827 msleep (10);
3828 } else {
3829 mdelay (10);
3830 }
3831 }
3832
3833 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3834 ioc->name, mpt_GetIocState(ioc, 0)));
3835 return -1;
3836}
3837
3838/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3839/**
3840 * mpt_diag_reset - Perform hard reset of the adapter.
3841 * @ioc: Pointer to MPT_ADAPTER structure
3842 * @ignore: Set if to honor and clear to ignore
3843 * the reset history bit
3844 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3845 * else set to NO_SLEEP (use mdelay instead)
3846 *
3847 * This routine places the adapter in diagnostic mode via the
3848 * WriteSequence register and then performs a hard reset of adapter
3849 * via the Diagnostic register. Adapter should be in ready state
3850 * upon successful completion.
3851 *
3852 * Returns: 1 hard reset successful
3853 * 0 no reset performed because reset history bit set
3854 * -2 enabling diagnostic mode failed
3855 * -3 diagnostic reset failed
3856 */
3857static int
3858mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3859{
3860 u32 diag0val;
3861 u32 doorbell;
3862 int hard_reset_done = 0;
3863 int count = 0;
3864 u32 diag1val = 0;
3865 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3866
3867 /* Clear any existing interrupts */
3868 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3869
3870 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3871 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3872 "address=%p\n", ioc->name, __func__,
3873 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3874 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3875 if (sleepFlag == CAN_SLEEP)
3876 msleep(1);
3877 else
3878 mdelay(1);
3879
3880 for (count = 0; count < 60; count ++) {
3881 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3882 doorbell &= MPI_IOC_STATE_MASK;
3883
3884 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3885 "looking for READY STATE: doorbell=%x"
3886 " count=%d\n",
3887 ioc->name, doorbell, count));
3888 if (doorbell == MPI_IOC_STATE_READY) {
3889 return 1;
3890 }
3891
3892 /* wait 1 sec */
3893 if (sleepFlag == CAN_SLEEP)
3894 msleep(1000);
3895 else
3896 mdelay(1000);
3897 }
3898 return -1;
3899 }
3900
3901 /* Use "Diagnostic reset" method! (only thing available!) */
3902 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3903
3904 if (ioc->debug_level & MPT_DEBUG) {
3905 if (ioc->alt_ioc)
3906 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3907 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3908 ioc->name, diag0val, diag1val));
3909 }
3910
3911 /* Do the reset if we are told to ignore the reset history
3912 * or if the reset history is 0
3913 */
3914 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3915 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3916 /* Write magic sequence to WriteSequence register
3917 * Loop until in diagnostic mode
3918 */
3919 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3920 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3921 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3922 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3923 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3924 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3925
3926 /* wait 100 msec */
3927 if (sleepFlag == CAN_SLEEP) {
3928 msleep (100);
3929 } else {
3930 mdelay (100);
3931 }
3932
3933 count++;
3934 if (count > 20) {
3935 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3936 ioc->name, diag0val);
3937 return -2;
3938
3939 }
3940
3941 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3942
3943 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3944 ioc->name, diag0val));
3945 }
3946
3947 if (ioc->debug_level & MPT_DEBUG) {
3948 if (ioc->alt_ioc)
3949 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3950 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3951 ioc->name, diag0val, diag1val));
3952 }
3953 /*
3954 * Disable the ARM (Bug fix)
3955 *
3956 */
3957 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3958 mdelay(1);
3959
3960 /*
3961 * Now hit the reset bit in the Diagnostic register
3962 * (THE BIG HAMMER!) (Clears DRWE bit).
3963 */
3964 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3965 hard_reset_done = 1;
3966 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3967 ioc->name));
3968
3969 /*
3970 * Call each currently registered protocol IOC reset handler
3971 * with pre-reset indication.
3972 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3973 * MptResetHandlers[] registered yet.
3974 */
3975 {
3976 u8 cb_idx;
3977 int r = 0;
3978
3979 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3980 if (MptResetHandlers[cb_idx]) {
3981 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3982 "Calling IOC pre_reset handler #%d\n",
3983 ioc->name, cb_idx));
3984 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3985 if (ioc->alt_ioc) {
3986 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3987 "Calling alt-%s pre_reset handler #%d\n",
3988 ioc->name, ioc->alt_ioc->name, cb_idx));
3989 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3990 }
3991 }
3992 }
3993 /* FIXME? Examine results here? */
3994 }
3995
3996 if (ioc->cached_fw)
3997 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3998 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3999 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4000 else
4001 cached_fw = NULL;
4002 if (cached_fw) {
4003 /* If the DownloadBoot operation fails, the
4004 * IOC will be left unusable. This is a fatal error
4005 * case. _diag_reset will return < 0
4006 */
4007 for (count = 0; count < 30; count ++) {
4008 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4009 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4010 break;
4011 }
4012
4013 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4014 ioc->name, diag0val, count));
4015 /* wait 1 sec */
4016 if (sleepFlag == CAN_SLEEP) {
4017 msleep (1000);
4018 } else {
4019 mdelay (1000);
4020 }
4021 }
4022 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4023 printk(MYIOC_s_WARN_FMT
4024 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4025 }
4026
4027 } else {
4028 /* Wait for FW to reload and for board
4029 * to go to the READY state.
4030 * Maximum wait is 60 seconds.
4031 * If fail, no error will check again
4032 * with calling program.
4033 */
4034 for (count = 0; count < 60; count ++) {
4035 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4036 doorbell &= MPI_IOC_STATE_MASK;
4037
4038 if (doorbell == MPI_IOC_STATE_READY) {
4039 break;
4040 }
4041
4042 /* wait 1 sec */
4043 if (sleepFlag == CAN_SLEEP) {
4044 msleep (1000);
4045 } else {
4046 mdelay (1000);
4047 }
4048 }
4049 }
4050 }
4051
4052 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4053 if (ioc->debug_level & MPT_DEBUG) {
4054 if (ioc->alt_ioc)
4055 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4056 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4057 ioc->name, diag0val, diag1val));
4058 }
4059
4060 /* Clear RESET_HISTORY bit! Place board in the
4061 * diagnostic mode to update the diag register.
4062 */
4063 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4064 count = 0;
4065 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4066 /* Write magic sequence to WriteSequence register
4067 * Loop until in diagnostic mode
4068 */
4069 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4070 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4071 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4072 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4073 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4074 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4075
4076 /* wait 100 msec */
4077 if (sleepFlag == CAN_SLEEP) {
4078 msleep (100);
4079 } else {
4080 mdelay (100);
4081 }
4082
4083 count++;
4084 if (count > 20) {
4085 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4086 ioc->name, diag0val);
4087 break;
4088 }
4089 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4090 }
4091 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4092 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4093 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4094 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4095 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4096 ioc->name);
4097 }
4098
4099 /* Disable Diagnostic Mode
4100 */
4101 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4102
4103 /* Check FW reload status flags.
4104 */
4105 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4106 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4107 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4108 ioc->name, diag0val);
4109 return -3;
4110 }
4111
4112 if (ioc->debug_level & MPT_DEBUG) {
4113 if (ioc->alt_ioc)
4114 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4115 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4116 ioc->name, diag0val, diag1val));
4117 }
4118
4119 /*
4120 * Reset flag that says we've enabled event notification
4121 */
4122 ioc->facts.EventState = 0;
4123
4124 if (ioc->alt_ioc)
4125 ioc->alt_ioc->facts.EventState = 0;
4126
4127 return hard_reset_done;
4128}
4129
4130/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4131/**
4132 * SendIocReset - Send IOCReset request to MPT adapter.
4133 * @ioc: Pointer to MPT_ADAPTER structure
4134 * @reset_type: reset type, expected values are
4135 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4136 * @sleepFlag: Specifies whether the process can sleep
4137 *
4138 * Send IOCReset request to the MPT adapter.
4139 *
4140 * Returns 0 for success, non-zero for failure.
4141 */
4142static int
4143SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4144{
4145 int r;
4146 u32 state;
4147 int cntdn, count;
4148
4149 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4150 ioc->name, reset_type));
4151 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4152 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4153 return r;
4154
4155 /* FW ACK'd request, wait for READY state
4156 */
4157 count = 0;
4158 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4159
4160 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4161 cntdn--;
4162 count++;
4163 if (!cntdn) {
4164 if (sleepFlag != CAN_SLEEP)
4165 count *= 10;
4166
4167 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
4168 ioc->name, (int)((count+5)/HZ));
4169 return -ETIME;
4170 }
4171
4172 if (sleepFlag == CAN_SLEEP) {
4173 msleep(1);
4174 } else {
4175 mdelay (1); /* 1 msec delay */
4176 }
4177 }
4178
4179 /* TODO!
4180 * Cleanup all event stuff for this IOC; re-issue EventNotification
4181 * request if needed.
4182 */
4183 if (ioc->facts.Function)
4184 ioc->facts.EventState = 0;
4185
4186 return 0;
4187}
4188
4189/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4190/**
4191 * initChainBuffers - Allocate memory for and initialize chain buffers
4192 * @ioc: Pointer to MPT_ADAPTER structure
4193 *
4194 * Allocates memory for and initializes chain buffers,
4195 * chain buffer control arrays and spinlock.
4196 */
4197static int
4198initChainBuffers(MPT_ADAPTER *ioc)
4199{
4200 u8 *mem;
4201 int sz, ii, num_chain;
4202 int scale, num_sge, numSGE;
4203
4204 /* ReqToChain size must equal the req_depth
4205 * index = req_idx
4206 */
4207 if (ioc->ReqToChain == NULL) {
4208 sz = ioc->req_depth * sizeof(int);
4209 mem = kmalloc(sz, GFP_ATOMIC);
4210 if (mem == NULL)
4211 return -1;
4212
4213 ioc->ReqToChain = (int *) mem;
4214 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4215 ioc->name, mem, sz));
4216 mem = kmalloc(sz, GFP_ATOMIC);
4217 if (mem == NULL)
4218 return -1;
4219
4220 ioc->RequestNB = (int *) mem;
4221 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4222 ioc->name, mem, sz));
4223 }
4224 for (ii = 0; ii < ioc->req_depth; ii++) {
4225 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4226 }
4227
4228 /* ChainToChain size must equal the total number
4229 * of chain buffers to be allocated.
4230 * index = chain_idx
4231 *
4232 * Calculate the number of chain buffers needed(plus 1) per I/O
4233 * then multiply the maximum number of simultaneous cmds
4234 *
4235 * num_sge = num sge in request frame + last chain buffer
4236 * scale = num sge per chain buffer if no chain element
4237 */
4238 scale = ioc->req_sz / ioc->SGE_size;
4239 if (ioc->sg_addr_size == sizeof(u64))
4240 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4241 else
4242 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4243
4244 if (ioc->sg_addr_size == sizeof(u64)) {
4245 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4246 (ioc->req_sz - 60) / ioc->SGE_size;
4247 } else {
4248 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4249 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4250 }
4251 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4252 ioc->name, num_sge, numSGE));
4253
4254 if ( numSGE > MPT_SCSI_SG_DEPTH )
4255 numSGE = MPT_SCSI_SG_DEPTH;
4256
4257 num_chain = 1;
4258 while (numSGE - num_sge > 0) {
4259 num_chain++;
4260 num_sge += (scale - 1);
4261 }
4262 num_chain++;
4263
4264 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4265 ioc->name, numSGE, num_sge, num_chain));
4266
4267 if (ioc->bus_type == SPI)
4268 num_chain *= MPT_SCSI_CAN_QUEUE;
4269 else
4270 num_chain *= MPT_FC_CAN_QUEUE;
4271
4272 ioc->num_chain = num_chain;
4273
4274 sz = num_chain * sizeof(int);
4275 if (ioc->ChainToChain == NULL) {
4276 mem = kmalloc(sz, GFP_ATOMIC);
4277 if (mem == NULL)
4278 return -1;
4279
4280 ioc->ChainToChain = (int *) mem;
4281 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4282 ioc->name, mem, sz));
4283 } else {
4284 mem = (u8 *) ioc->ChainToChain;
4285 }
4286 memset(mem, 0xFF, sz);
4287 return num_chain;
4288}
4289
4290/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4291/**
4292 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4293 * @ioc: Pointer to MPT_ADAPTER structure
4294 *
4295 * This routine allocates memory for the MPT reply and request frame
4296 * pools (if necessary), and primes the IOC reply FIFO with
4297 * reply frames.
4298 *
4299 * Returns 0 for success, non-zero for failure.
4300 */
4301static int
4302PrimeIocFifos(MPT_ADAPTER *ioc)
4303{
4304 MPT_FRAME_HDR *mf;
4305 unsigned long flags;
4306 dma_addr_t alloc_dma;
4307 u8 *mem;
4308 int i, reply_sz, sz, total_size, num_chain;
4309 u64 dma_mask;
4310
4311 dma_mask = 0;
4312
4313 /* Prime reply FIFO... */
4314
4315 if (ioc->reply_frames == NULL) {
4316 if ( (num_chain = initChainBuffers(ioc)) < 0)
4317 return -1;
4318 /*
4319 * 1078 errata workaround for the 36GB limitation
4320 */
4321 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4322 ioc->dma_mask > DMA_35BIT_MASK) {
4323 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4324 && !pci_set_consistent_dma_mask(ioc->pcidev,
4325 DMA_BIT_MASK(32))) {
4326 dma_mask = DMA_35BIT_MASK;
4327 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4328 "setting 35 bit addressing for "
4329 "Request/Reply/Chain and Sense Buffers\n",
4330 ioc->name));
4331 } else {
4332 /*Reseting DMA mask to 64 bit*/
4333 pci_set_dma_mask(ioc->pcidev,
4334 DMA_BIT_MASK(64));
4335 pci_set_consistent_dma_mask(ioc->pcidev,
4336 DMA_BIT_MASK(64));
4337
4338 printk(MYIOC_s_ERR_FMT
4339 "failed setting 35 bit addressing for "
4340 "Request/Reply/Chain and Sense Buffers\n",
4341 ioc->name);
4342 return -1;
4343 }
4344 }
4345
4346 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4347 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4348 ioc->name, ioc->reply_sz, ioc->reply_depth));
4349 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4350 ioc->name, reply_sz, reply_sz));
4351
4352 sz = (ioc->req_sz * ioc->req_depth);
4353 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4354 ioc->name, ioc->req_sz, ioc->req_depth));
4355 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4356 ioc->name, sz, sz));
4357 total_size += sz;
4358
4359 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4360 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4361 ioc->name, ioc->req_sz, num_chain));
4362 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4363 ioc->name, sz, sz, num_chain));
4364
4365 total_size += sz;
4366 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4367 if (mem == NULL) {
4368 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4369 ioc->name);
4370 goto out_fail;
4371 }
4372
4373 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4374 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4375
4376 memset(mem, 0, total_size);
4377 ioc->alloc_total += total_size;
4378 ioc->alloc = mem;
4379 ioc->alloc_dma = alloc_dma;
4380 ioc->alloc_sz = total_size;
4381 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4382 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4383
4384 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4385 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4386
4387 alloc_dma += reply_sz;
4388 mem += reply_sz;
4389
4390 /* Request FIFO - WE manage this! */
4391
4392 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4393 ioc->req_frames_dma = alloc_dma;
4394
4395 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4396 ioc->name, mem, (void *)(ulong)alloc_dma));
4397
4398 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4399
4400#if defined(CONFIG_MTRR) && 0
4401 /*
4402 * Enable Write Combining MTRR for IOC's memory region.
4403 * (at least as much as we can; "size and base must be
4404 * multiples of 4 kiB"
4405 */
4406 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4407 sz,
4408 MTRR_TYPE_WRCOMB, 1);
4409 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4410 ioc->name, ioc->req_frames_dma, sz));
4411#endif
4412
4413 for (i = 0; i < ioc->req_depth; i++) {
4414 alloc_dma += ioc->req_sz;
4415 mem += ioc->req_sz;
4416 }
4417
4418 ioc->ChainBuffer = mem;
4419 ioc->ChainBufferDMA = alloc_dma;
4420
4421 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4422 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4423
4424 /* Initialize the free chain Q.
4425 */
4426
4427 INIT_LIST_HEAD(&ioc->FreeChainQ);
4428
4429 /* Post the chain buffers to the FreeChainQ.
4430 */
4431 mem = (u8 *)ioc->ChainBuffer;
4432 for (i=0; i < num_chain; i++) {
4433 mf = (MPT_FRAME_HDR *) mem;
4434 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4435 mem += ioc->req_sz;
4436 }
4437
4438 /* Initialize Request frames linked list
4439 */
4440 alloc_dma = ioc->req_frames_dma;
4441 mem = (u8 *) ioc->req_frames;
4442
4443 spin_lock_irqsave(&ioc->FreeQlock, flags);
4444 INIT_LIST_HEAD(&ioc->FreeQ);
4445 for (i = 0; i < ioc->req_depth; i++) {
4446 mf = (MPT_FRAME_HDR *) mem;
4447
4448 /* Queue REQUESTs *internally*! */
4449 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4450
4451 mem += ioc->req_sz;
4452 }
4453 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4454
4455 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4456 ioc->sense_buf_pool =
4457 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4458 if (ioc->sense_buf_pool == NULL) {
4459 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4460 ioc->name);
4461 goto out_fail;
4462 }
4463
4464 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4465 ioc->alloc_total += sz;
4466 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4467 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4468
4469 }
4470
4471 /* Post Reply frames to FIFO
4472 */
4473 alloc_dma = ioc->alloc_dma;
4474 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4475 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4476
4477 for (i = 0; i < ioc->reply_depth; i++) {
4478 /* Write each address to the IOC! */
4479 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4480 alloc_dma += ioc->reply_sz;
4481 }
4482
4483 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4484 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4485 ioc->dma_mask))
4486 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4487 "restoring 64 bit addressing\n", ioc->name));
4488
4489 return 0;
4490
4491out_fail:
4492 if (ioc->alloc != NULL) {
4493 sz = ioc->alloc_sz;
4494 pci_free_consistent(ioc->pcidev,
4495 sz,
4496 ioc->alloc, ioc->alloc_dma);
4497 ioc->reply_frames = NULL;
4498 ioc->req_frames = NULL;
4499 ioc->alloc_total -= sz;
4500 }
4501 if (ioc->sense_buf_pool != NULL) {
4502 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4503 pci_free_consistent(ioc->pcidev,
4504 sz,
4505 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4506 ioc->sense_buf_pool = NULL;
4507 }
4508
4509 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4510 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4511 DMA_BIT_MASK(64)))
4512 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4513 "restoring 64 bit addressing\n", ioc->name));
4514
4515 return -1;
4516}
4517
4518/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4519/**
4520 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4521 * from IOC via doorbell handshake method.
4522 * @ioc: Pointer to MPT_ADAPTER structure
4523 * @reqBytes: Size of the request in bytes
4524 * @req: Pointer to MPT request frame
4525 * @replyBytes: Expected size of the reply in bytes
4526 * @u16reply: Pointer to area where reply should be written
4527 * @maxwait: Max wait time for a reply (in seconds)
4528 * @sleepFlag: Specifies whether the process can sleep
4529 *
4530 * NOTES: It is the callers responsibility to byte-swap fields in the
4531 * request which are greater than 1 byte in size. It is also the
4532 * callers responsibility to byte-swap response fields which are
4533 * greater than 1 byte in size.
4534 *
4535 * Returns 0 for success, non-zero for failure.
4536 */
4537static int
4538mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4539 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4540{
4541 MPIDefaultReply_t *mptReply;
4542 int failcnt = 0;
4543 int t;
4544
4545 /*
4546 * Get ready to cache a handshake reply
4547 */
4548 ioc->hs_reply_idx = 0;
4549 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4550 mptReply->MsgLength = 0;
4551
4552 /*
4553 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4554 * then tell IOC that we want to handshake a request of N words.
4555 * (WRITE u32val to Doorbell reg).
4556 */
4557 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4558 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4559 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4560 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4561
4562 /*
4563 * Wait for IOC's doorbell handshake int
4564 */
4565 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4566 failcnt++;
4567
4568 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4569 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4570
4571 /* Read doorbell and check for active bit */
4572 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4573 return -1;
4574
4575 /*
4576 * Clear doorbell int (WRITE 0 to IntStatus reg),
4577 * then wait for IOC to ACKnowledge that it's ready for
4578 * our handshake request.
4579 */
4580 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4581 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4582 failcnt++;
4583
4584 if (!failcnt) {
4585 int ii;
4586 u8 *req_as_bytes = (u8 *) req;
4587
4588 /*
4589 * Stuff request words via doorbell handshake,
4590 * with ACK from IOC for each.
4591 */
4592 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4593 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4594 (req_as_bytes[(ii*4) + 1] << 8) |
4595 (req_as_bytes[(ii*4) + 2] << 16) |
4596 (req_as_bytes[(ii*4) + 3] << 24));
4597
4598 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4599 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4600 failcnt++;
4601 }
4602
4603 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4604 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4605
4606 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4607 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4608
4609 /*
4610 * Wait for completion of doorbell handshake reply from the IOC
4611 */
4612 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4613 failcnt++;
4614
4615 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4616 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4617
4618 /*
4619 * Copy out the cached reply...
4620 */
4621 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4622 u16reply[ii] = ioc->hs_reply[ii];
4623 } else {
4624 return -99;
4625 }
4626
4627 return -failcnt;
4628}
4629
4630/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4631/**
4632 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4633 * @ioc: Pointer to MPT_ADAPTER structure
4634 * @howlong: How long to wait (in seconds)
4635 * @sleepFlag: Specifies whether the process can sleep
4636 *
4637 * This routine waits (up to ~2 seconds max) for IOC doorbell
4638 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4639 * bit in its IntStatus register being clear.
4640 *
4641 * Returns a negative value on failure, else wait loop count.
4642 */
4643static int
4644WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4645{
4646 int cntdn;
4647 int count = 0;
4648 u32 intstat=0;
4649
4650 cntdn = 1000 * howlong;
4651
4652 if (sleepFlag == CAN_SLEEP) {
4653 while (--cntdn) {
4654 msleep (1);
4655 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4656 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4657 break;
4658 count++;
4659 }
4660 } else {
4661 while (--cntdn) {
4662 udelay (1000);
4663 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4664 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4665 break;
4666 count++;
4667 }
4668 }
4669
4670 if (cntdn) {
4671 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4672 ioc->name, count));
4673 return count;
4674 }
4675
4676 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4677 ioc->name, count, intstat);
4678 return -1;
4679}
4680
4681/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4682/**
4683 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4684 * @ioc: Pointer to MPT_ADAPTER structure
4685 * @howlong: How long to wait (in seconds)
4686 * @sleepFlag: Specifies whether the process can sleep
4687 *
4688 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4689 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4690 *
4691 * Returns a negative value on failure, else wait loop count.
4692 */
4693static int
4694WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4695{
4696 int cntdn;
4697 int count = 0;
4698 u32 intstat=0;
4699
4700 cntdn = 1000 * howlong;
4701 if (sleepFlag == CAN_SLEEP) {
4702 while (--cntdn) {
4703 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4704 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4705 break;
4706 msleep(1);
4707 count++;
4708 }
4709 } else {
4710 while (--cntdn) {
4711 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4712 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4713 break;
4714 udelay (1000);
4715 count++;
4716 }
4717 }
4718
4719 if (cntdn) {
4720 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4721 ioc->name, count, howlong));
4722 return count;
4723 }
4724
4725 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4726 ioc->name, count, intstat);
4727 return -1;
4728}
4729
4730/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4731/**
4732 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4733 * @ioc: Pointer to MPT_ADAPTER structure
4734 * @howlong: How long to wait (in seconds)
4735 * @sleepFlag: Specifies whether the process can sleep
4736 *
4737 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4738 * Reply is cached to IOC private area large enough to hold a maximum
4739 * of 128 bytes of reply data.
4740 *
4741 * Returns a negative value on failure, else size of reply in WORDS.
4742 */
4743static int
4744WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4745{
4746 int u16cnt = 0;
4747 int failcnt = 0;
4748 int t;
4749 u16 *hs_reply = ioc->hs_reply;
4750 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4751 u16 hword;
4752
4753 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4754
4755 /*
4756 * Get first two u16's so we can look at IOC's intended reply MsgLength
4757 */
4758 u16cnt=0;
4759 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4760 failcnt++;
4761 } else {
4762 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4763 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4764 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4765 failcnt++;
4766 else {
4767 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4768 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4769 }
4770 }
4771
4772 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4773 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4774 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4775
4776 /*
4777 * If no error (and IOC said MsgLength is > 0), piece together
4778 * reply 16 bits at a time.
4779 */
4780 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4781 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4782 failcnt++;
4783 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4784 /* don't overflow our IOC hs_reply[] buffer! */
4785 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4786 hs_reply[u16cnt] = hword;
4787 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4788 }
4789
4790 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4791 failcnt++;
4792 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4793
4794 if (failcnt) {
4795 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4796 ioc->name);
4797 return -failcnt;
4798 }
4799#if 0
4800 else if (u16cnt != (2 * mptReply->MsgLength)) {
4801 return -101;
4802 }
4803 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4804 return -102;
4805 }
4806#endif
4807
4808 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4809 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4810
4811 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4812 ioc->name, t, u16cnt/2));
4813 return u16cnt/2;
4814}
4815
4816/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4817/**
4818 * GetLanConfigPages - Fetch LANConfig pages.
4819 * @ioc: Pointer to MPT_ADAPTER structure
4820 *
4821 * Return: 0 for success
4822 * -ENOMEM if no memory available
4823 * -EPERM if not allowed due to ISR context
4824 * -EAGAIN if no msg frames currently available
4825 * -EFAULT for non-successful reply or no reply (timeout)
4826 */
4827static int
4828GetLanConfigPages(MPT_ADAPTER *ioc)
4829{
4830 ConfigPageHeader_t hdr;
4831 CONFIGPARMS cfg;
4832 LANPage0_t *ppage0_alloc;
4833 dma_addr_t page0_dma;
4834 LANPage1_t *ppage1_alloc;
4835 dma_addr_t page1_dma;
4836 int rc = 0;
4837 int data_sz;
4838 int copy_sz;
4839
4840 /* Get LAN Page 0 header */
4841 hdr.PageVersion = 0;
4842 hdr.PageLength = 0;
4843 hdr.PageNumber = 0;
4844 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4845 cfg.cfghdr.hdr = &hdr;
4846 cfg.physAddr = -1;
4847 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4848 cfg.dir = 0;
4849 cfg.pageAddr = 0;
4850 cfg.timeout = 0;
4851
4852 if ((rc = mpt_config(ioc, &cfg)) != 0)
4853 return rc;
4854
4855 if (hdr.PageLength > 0) {
4856 data_sz = hdr.PageLength * 4;
4857 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4858 rc = -ENOMEM;
4859 if (ppage0_alloc) {
4860 memset((u8 *)ppage0_alloc, 0, data_sz);
4861 cfg.physAddr = page0_dma;
4862 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4863
4864 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4865 /* save the data */
4866 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4867 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4868
4869 }
4870
4871 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4872
4873 /* FIXME!
4874 * Normalize endianness of structure data,
4875 * by byte-swapping all > 1 byte fields!
4876 */
4877
4878 }
4879
4880 if (rc)
4881 return rc;
4882 }
4883
4884 /* Get LAN Page 1 header */
4885 hdr.PageVersion = 0;
4886 hdr.PageLength = 0;
4887 hdr.PageNumber = 1;
4888 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4889 cfg.cfghdr.hdr = &hdr;
4890 cfg.physAddr = -1;
4891 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4892 cfg.dir = 0;
4893 cfg.pageAddr = 0;
4894
4895 if ((rc = mpt_config(ioc, &cfg)) != 0)
4896 return rc;
4897
4898 if (hdr.PageLength == 0)
4899 return 0;
4900
4901 data_sz = hdr.PageLength * 4;
4902 rc = -ENOMEM;
4903 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4904 if (ppage1_alloc) {
4905 memset((u8 *)ppage1_alloc, 0, data_sz);
4906 cfg.physAddr = page1_dma;
4907 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4908
4909 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4910 /* save the data */
4911 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4912 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4913 }
4914
4915 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4916
4917 /* FIXME!
4918 * Normalize endianness of structure data,
4919 * by byte-swapping all > 1 byte fields!
4920 */
4921
4922 }
4923
4924 return rc;
4925}
4926
4927/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4928/**
4929 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4930 * @ioc: Pointer to MPT_ADAPTER structure
4931 * @persist_opcode: see below
4932 *
4933 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4934 * devices not currently present.
4935 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4936 *
4937 * NOTE: Don't use not this function during interrupt time.
4938 *
4939 * Returns 0 for success, non-zero error
4940 */
4941
4942/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4943int
4944mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4945{
4946 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4947 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4948 MPT_FRAME_HDR *mf = NULL;
4949 MPIHeader_t *mpi_hdr;
4950
4951
4952 /* insure garbage is not sent to fw */
4953 switch(persist_opcode) {
4954
4955 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4956 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4957 break;
4958
4959 default:
4960 return -1;
4961 break;
4962 }
4963
4964 printk("%s: persist_opcode=%x\n",__func__, persist_opcode);
4965
4966 /* Get a MF for this command.
4967 */
4968 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4969 printk("%s: no msg frames!\n",__func__);
4970 return -1;
4971 }
4972
4973 mpi_hdr = (MPIHeader_t *) mf;
4974 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4975 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4976 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4977 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4978 sasIoUnitCntrReq->Operation = persist_opcode;
4979
4980 init_timer(&ioc->persist_timer);
4981 ioc->persist_timer.data = (unsigned long) ioc;
4982 ioc->persist_timer.function = mpt_timer_expired;
4983 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4984 ioc->persist_wait_done=0;
4985 add_timer(&ioc->persist_timer);
4986 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4987 wait_event(mpt_waitq, ioc->persist_wait_done);
4988
4989 sasIoUnitCntrReply =
4990 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4991 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4992 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4993 __func__,
4994 sasIoUnitCntrReply->IOCStatus,
4995 sasIoUnitCntrReply->IOCLogInfo);
4996 return -1;
4997 }
4998
4999 printk("%s: success\n",__func__);
5000 return 0;
5001}
5002
5003/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5004
5005static void
5006mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5007 MpiEventDataRaid_t * pRaidEventData)
5008{
5009 int volume;
5010 int reason;
5011 int disk;
5012 int status;
5013 int flags;
5014 int state;
5015
5016 volume = pRaidEventData->VolumeID;
5017 reason = pRaidEventData->ReasonCode;
5018 disk = pRaidEventData->PhysDiskNum;
5019 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5020 flags = (status >> 0) & 0xff;
5021 state = (status >> 8) & 0xff;
5022
5023 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5024 return;
5025 }
5026
5027 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5028 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5029 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5030 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5031 ioc->name, disk, volume);
5032 } else {
5033 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5034 ioc->name, volume);
5035 }
5036
5037 switch(reason) {
5038 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5039 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5040 ioc->name);
5041 break;
5042
5043 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5044
5045 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5046 ioc->name);
5047 break;
5048
5049 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5050 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5051 ioc->name);
5052 break;
5053
5054 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5055 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5056 ioc->name,
5057 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5058 ? "optimal"
5059 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5060 ? "degraded"
5061 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5062 ? "failed"
5063 : "state unknown",
5064 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5065 ? ", enabled" : "",
5066 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5067 ? ", quiesced" : "",
5068 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5069 ? ", resync in progress" : "" );
5070 break;
5071
5072 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5073 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5074 ioc->name, disk);
5075 break;
5076
5077 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5078 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5079 ioc->name);
5080 break;
5081
5082 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5083 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5084 ioc->name);
5085 break;
5086
5087 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5088 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5089 ioc->name);
5090 break;
5091
5092 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5093 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5094 ioc->name,
5095 state == MPI_PHYSDISK0_STATUS_ONLINE
5096 ? "online"
5097 : state == MPI_PHYSDISK0_STATUS_MISSING
5098 ? "missing"
5099 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5100 ? "not compatible"
5101 : state == MPI_PHYSDISK0_STATUS_FAILED
5102 ? "failed"
5103 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5104 ? "initializing"
5105 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5106 ? "offline requested"
5107 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5108 ? "failed requested"
5109 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5110 ? "offline"
5111 : "state unknown",
5112 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5113 ? ", out of sync" : "",
5114 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5115 ? ", quiesced" : "" );
5116 break;
5117
5118 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5119 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5120 ioc->name, disk);
5121 break;
5122
5123 case MPI_EVENT_RAID_RC_SMART_DATA:
5124 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5125 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5126 break;
5127
5128 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5129 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5130 ioc->name, disk);
5131 break;
5132 }
5133}
5134
5135/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5136/**
5137 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5138 * @ioc: Pointer to MPT_ADAPTER structure
5139 *
5140 * Returns: 0 for success
5141 * -ENOMEM if no memory available
5142 * -EPERM if not allowed due to ISR context
5143 * -EAGAIN if no msg frames currently available
5144 * -EFAULT for non-successful reply or no reply (timeout)
5145 */
5146static int
5147GetIoUnitPage2(MPT_ADAPTER *ioc)
5148{
5149 ConfigPageHeader_t hdr;
5150 CONFIGPARMS cfg;
5151 IOUnitPage2_t *ppage_alloc;
5152 dma_addr_t page_dma;
5153 int data_sz;
5154 int rc;
5155
5156 /* Get the page header */
5157 hdr.PageVersion = 0;
5158 hdr.PageLength = 0;
5159 hdr.PageNumber = 2;
5160 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5161 cfg.cfghdr.hdr = &hdr;
5162 cfg.physAddr = -1;
5163 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5164 cfg.dir = 0;
5165 cfg.pageAddr = 0;
5166 cfg.timeout = 0;
5167
5168 if ((rc = mpt_config(ioc, &cfg)) != 0)
5169 return rc;
5170
5171 if (hdr.PageLength == 0)
5172 return 0;
5173
5174 /* Read the config page */
5175 data_sz = hdr.PageLength * 4;
5176 rc = -ENOMEM;
5177 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5178 if (ppage_alloc) {
5179 memset((u8 *)ppage_alloc, 0, data_sz);
5180 cfg.physAddr = page_dma;
5181 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5182
5183 /* If Good, save data */
5184 if ((rc = mpt_config(ioc, &cfg)) == 0)
5185 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5186
5187 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5188 }
5189
5190 return rc;
5191}
5192
5193/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5194/**
5195 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5196 * @ioc: Pointer to a Adapter Strucutre
5197 * @portnum: IOC port number
5198 *
5199 * Return: -EFAULT if read of config page header fails
5200 * or if no nvram
5201 * If read of SCSI Port Page 0 fails,
5202 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5203 * Adapter settings: async, narrow
5204 * Return 1
5205 * If read of SCSI Port Page 2 fails,
5206 * Adapter settings valid
5207 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5208 * Return 1
5209 * Else
5210 * Both valid
5211 * Return 0
5212 * CHECK - what type of locking mechanisms should be used????
5213 */
5214static int
5215mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5216{
5217 u8 *pbuf;
5218 dma_addr_t buf_dma;
5219 CONFIGPARMS cfg;
5220 ConfigPageHeader_t header;
5221 int ii;
5222 int data, rc = 0;
5223
5224 /* Allocate memory
5225 */
5226 if (!ioc->spi_data.nvram) {
5227 int sz;
5228 u8 *mem;
5229 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5230 mem = kmalloc(sz, GFP_ATOMIC);
5231 if (mem == NULL)
5232 return -EFAULT;
5233
5234 ioc->spi_data.nvram = (int *) mem;
5235
5236 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5237 ioc->name, ioc->spi_data.nvram, sz));
5238 }
5239
5240 /* Invalidate NVRAM information
5241 */
5242 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5243 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5244 }
5245
5246 /* Read SPP0 header, allocate memory, then read page.
5247 */
5248 header.PageVersion = 0;
5249 header.PageLength = 0;
5250 header.PageNumber = 0;
5251 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5252 cfg.cfghdr.hdr = &header;
5253 cfg.physAddr = -1;
5254 cfg.pageAddr = portnum;
5255 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5256 cfg.dir = 0;
5257 cfg.timeout = 0; /* use default */
5258 if (mpt_config(ioc, &cfg) != 0)
5259 return -EFAULT;
5260
5261 if (header.PageLength > 0) {
5262 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5263 if (pbuf) {
5264 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5265 cfg.physAddr = buf_dma;
5266 if (mpt_config(ioc, &cfg) != 0) {
5267 ioc->spi_data.maxBusWidth = MPT_NARROW;
5268 ioc->spi_data.maxSyncOffset = 0;
5269 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5270 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5271 rc = 1;
5272 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5273 "Unable to read PortPage0 minSyncFactor=%x\n",
5274 ioc->name, ioc->spi_data.minSyncFactor));
5275 } else {
5276 /* Save the Port Page 0 data
5277 */
5278 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5279 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5280 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5281
5282 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5283 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5284 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5285 "noQas due to Capabilities=%x\n",
5286 ioc->name, pPP0->Capabilities));
5287 }
5288 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5289 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5290 if (data) {
5291 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5292 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5293 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5294 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5295 "PortPage0 minSyncFactor=%x\n",
5296 ioc->name, ioc->spi_data.minSyncFactor));
5297 } else {
5298 ioc->spi_data.maxSyncOffset = 0;
5299 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5300 }
5301
5302 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5303
5304 /* Update the minSyncFactor based on bus type.
5305 */
5306 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5307 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5308
5309 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5310 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5311 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5312 "HVD or SE detected, minSyncFactor=%x\n",
5313 ioc->name, ioc->spi_data.minSyncFactor));
5314 }
5315 }
5316 }
5317 if (pbuf) {
5318 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5319 }
5320 }
5321 }
5322
5323 /* SCSI Port Page 2 - Read the header then the page.
5324 */
5325 header.PageVersion = 0;
5326 header.PageLength = 0;
5327 header.PageNumber = 2;
5328 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5329 cfg.cfghdr.hdr = &header;
5330 cfg.physAddr = -1;
5331 cfg.pageAddr = portnum;
5332 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5333 cfg.dir = 0;
5334 if (mpt_config(ioc, &cfg) != 0)
5335 return -EFAULT;
5336
5337 if (header.PageLength > 0) {
5338 /* Allocate memory and read SCSI Port Page 2
5339 */
5340 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5341 if (pbuf) {
5342 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5343 cfg.physAddr = buf_dma;
5344 if (mpt_config(ioc, &cfg) != 0) {
5345 /* Nvram data is left with INVALID mark
5346 */
5347 rc = 1;
5348 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5349
5350 /* This is an ATTO adapter, read Page2 accordingly
5351 */
5352 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5353 ATTODeviceInfo_t *pdevice = NULL;
5354 u16 ATTOFlags;
5355
5356 /* Save the Port Page 2 data
5357 * (reformat into a 32bit quantity)
5358 */
5359 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5360 pdevice = &pPP2->DeviceSettings[ii];
5361 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5362 data = 0;
5363
5364 /* Translate ATTO device flags to LSI format
5365 */
5366 if (ATTOFlags & ATTOFLAG_DISC)
5367 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5368 if (ATTOFlags & ATTOFLAG_ID_ENB)
5369 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5370 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5371 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5372 if (ATTOFlags & ATTOFLAG_TAGGED)
5373 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5374 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5375 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5376
5377 data = (data << 16) | (pdevice->Period << 8) | 10;
5378 ioc->spi_data.nvram[ii] = data;
5379 }
5380 } else {
5381 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5382 MpiDeviceInfo_t *pdevice = NULL;
5383
5384 /*
5385 * Save "Set to Avoid SCSI Bus Resets" flag
5386 */
5387 ioc->spi_data.bus_reset =
5388 (le32_to_cpu(pPP2->PortFlags) &
5389 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5390 0 : 1 ;
5391
5392 /* Save the Port Page 2 data
5393 * (reformat into a 32bit quantity)
5394 */
5395 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5396 ioc->spi_data.PortFlags = data;
5397 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5398 pdevice = &pPP2->DeviceSettings[ii];
5399 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5400 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5401 ioc->spi_data.nvram[ii] = data;
5402 }
5403 }
5404
5405 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5406 }
5407 }
5408
5409 /* Update Adapter limits with those from NVRAM
5410 * Comment: Don't need to do this. Target performance
5411 * parameters will never exceed the adapters limits.
5412 */
5413
5414 return rc;
5415}
5416
5417/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5418/**
5419 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5420 * @ioc: Pointer to a Adapter Strucutre
5421 * @portnum: IOC port number
5422 *
5423 * Return: -EFAULT if read of config page header fails
5424 * or 0 if success.
5425 */
5426static int
5427mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5428{
5429 CONFIGPARMS cfg;
5430 ConfigPageHeader_t header;
5431
5432 /* Read the SCSI Device Page 1 header
5433 */
5434 header.PageVersion = 0;
5435 header.PageLength = 0;
5436 header.PageNumber = 1;
5437 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5438 cfg.cfghdr.hdr = &header;
5439 cfg.physAddr = -1;
5440 cfg.pageAddr = portnum;
5441 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5442 cfg.dir = 0;
5443 cfg.timeout = 0;
5444 if (mpt_config(ioc, &cfg) != 0)
5445 return -EFAULT;
5446
5447 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5448 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5449
5450 header.PageVersion = 0;
5451 header.PageLength = 0;
5452 header.PageNumber = 0;
5453 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5454 if (mpt_config(ioc, &cfg) != 0)
5455 return -EFAULT;
5456
5457 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5458 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5459
5460 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5461 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5462
5463 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5464 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5465 return 0;
5466}
5467
5468/**
5469 * mpt_inactive_raid_list_free - This clears this link list.
5470 * @ioc : pointer to per adapter structure
5471 **/
5472static void
5473mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5474{
5475 struct inactive_raid_component_info *component_info, *pNext;
5476
5477 if (list_empty(&ioc->raid_data.inactive_list))
5478 return;
5479
5480 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5481 list_for_each_entry_safe(component_info, pNext,
5482 &ioc->raid_data.inactive_list, list) {
5483 list_del(&component_info->list);
5484 kfree(component_info);
5485 }
5486 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5487}
5488
5489/**
5490 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5491 *
5492 * @ioc : pointer to per adapter structure
5493 * @channel : volume channel
5494 * @id : volume target id
5495 **/
5496static void
5497mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5498{
5499 CONFIGPARMS cfg;
5500 ConfigPageHeader_t hdr;
5501 dma_addr_t dma_handle;
5502 pRaidVolumePage0_t buffer = NULL;
5503 int i;
5504 RaidPhysDiskPage0_t phys_disk;
5505 struct inactive_raid_component_info *component_info;
5506 int handle_inactive_volumes;
5507
5508 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5509 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5510 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5511 cfg.pageAddr = (channel << 8) + id;
5512 cfg.cfghdr.hdr = &hdr;
5513 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5514
5515 if (mpt_config(ioc, &cfg) != 0)
5516 goto out;
5517
5518 if (!hdr.PageLength)
5519 goto out;
5520
5521 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5522 &dma_handle);
5523
5524 if (!buffer)
5525 goto out;
5526
5527 cfg.physAddr = dma_handle;
5528 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5529
5530 if (mpt_config(ioc, &cfg) != 0)
5531 goto out;
5532
5533 if (!buffer->NumPhysDisks)
5534 goto out;
5535
5536 handle_inactive_volumes =
5537 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5538 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5539 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5540 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5541
5542 if (!handle_inactive_volumes)
5543 goto out;
5544
5545 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5546 for (i = 0; i < buffer->NumPhysDisks; i++) {
5547 if(mpt_raid_phys_disk_pg0(ioc,
5548 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5549 continue;
5550
5551 if ((component_info = kmalloc(sizeof (*component_info),
5552 GFP_KERNEL)) == NULL)
5553 continue;
5554
5555 component_info->volumeID = id;
5556 component_info->volumeBus = channel;
5557 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5558 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5559 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5560 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5561
5562 list_add_tail(&component_info->list,
5563 &ioc->raid_data.inactive_list);
5564 }
5565 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5566
5567 out:
5568 if (buffer)
5569 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5570 dma_handle);
5571}
5572
5573/**
5574 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5575 * @ioc: Pointer to a Adapter Structure
5576 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5577 * @phys_disk: requested payload data returned
5578 *
5579 * Return:
5580 * 0 on success
5581 * -EFAULT if read of config page header fails or data pointer not NULL
5582 * -ENOMEM if pci_alloc failed
5583 **/
5584int
5585mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5586{
5587 CONFIGPARMS cfg;
5588 ConfigPageHeader_t hdr;
5589 dma_addr_t dma_handle;
5590 pRaidPhysDiskPage0_t buffer = NULL;
5591 int rc;
5592
5593 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5594 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5595
5596 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5597 cfg.cfghdr.hdr = &hdr;
5598 cfg.physAddr = -1;
5599 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5600
5601 if (mpt_config(ioc, &cfg) != 0) {
5602 rc = -EFAULT;
5603 goto out;
5604 }
5605
5606 if (!hdr.PageLength) {
5607 rc = -EFAULT;
5608 goto out;
5609 }
5610
5611 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5612 &dma_handle);
5613
5614 if (!buffer) {
5615 rc = -ENOMEM;
5616 goto out;
5617 }
5618
5619 cfg.physAddr = dma_handle;
5620 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5621 cfg.pageAddr = phys_disk_num;
5622
5623 if (mpt_config(ioc, &cfg) != 0) {
5624 rc = -EFAULT;
5625 goto out;
5626 }
5627
5628 rc = 0;
5629 memcpy(phys_disk, buffer, sizeof(*buffer));
5630 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5631
5632 out:
5633
5634 if (buffer)
5635 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5636 dma_handle);
5637
5638 return rc;
5639}
5640
5641/**
5642 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5643 * @ioc: Pointer to a Adapter Strucutre
5644 *
5645 * Return:
5646 * 0 on success
5647 * -EFAULT if read of config page header fails or data pointer not NULL
5648 * -ENOMEM if pci_alloc failed
5649 **/
5650int
5651mpt_findImVolumes(MPT_ADAPTER *ioc)
5652{
5653 IOCPage2_t *pIoc2;
5654 u8 *mem;
5655 dma_addr_t ioc2_dma;
5656 CONFIGPARMS cfg;
5657 ConfigPageHeader_t header;
5658 int rc = 0;
5659 int iocpage2sz;
5660 int i;
5661
5662 if (!ioc->ir_firmware)
5663 return 0;
5664
5665 /* Free the old page
5666 */
5667 kfree(ioc->raid_data.pIocPg2);
5668 ioc->raid_data.pIocPg2 = NULL;
5669 mpt_inactive_raid_list_free(ioc);
5670
5671 /* Read IOCP2 header then the page.
5672 */
5673 header.PageVersion = 0;
5674 header.PageLength = 0;
5675 header.PageNumber = 2;
5676 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5677 cfg.cfghdr.hdr = &header;
5678 cfg.physAddr = -1;
5679 cfg.pageAddr = 0;
5680 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5681 cfg.dir = 0;
5682 cfg.timeout = 0;
5683 if (mpt_config(ioc, &cfg) != 0)
5684 return -EFAULT;
5685
5686 if (header.PageLength == 0)
5687 return -EFAULT;
5688
5689 iocpage2sz = header.PageLength * 4;
5690 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5691 if (!pIoc2)
5692 return -ENOMEM;
5693
5694 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5695 cfg.physAddr = ioc2_dma;
5696 if (mpt_config(ioc, &cfg) != 0)
5697 goto out;
5698
5699 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5700 if (!mem)
5701 goto out;
5702
5703 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5704 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5705
5706 mpt_read_ioc_pg_3(ioc);
5707
5708 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5709 mpt_inactive_raid_volumes(ioc,
5710 pIoc2->RaidVolume[i].VolumeBus,
5711 pIoc2->RaidVolume[i].VolumeID);
5712
5713 out:
5714 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5715
5716 return rc;
5717}
5718
5719static int
5720mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5721{
5722 IOCPage3_t *pIoc3;
5723 u8 *mem;
5724 CONFIGPARMS cfg;
5725 ConfigPageHeader_t header;
5726 dma_addr_t ioc3_dma;
5727 int iocpage3sz = 0;
5728
5729 /* Free the old page
5730 */
5731 kfree(ioc->raid_data.pIocPg3);
5732 ioc->raid_data.pIocPg3 = NULL;
5733
5734 /* There is at least one physical disk.
5735 * Read and save IOC Page 3
5736 */
5737 header.PageVersion = 0;
5738 header.PageLength = 0;
5739 header.PageNumber = 3;
5740 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5741 cfg.cfghdr.hdr = &header;
5742 cfg.physAddr = -1;
5743 cfg.pageAddr = 0;
5744 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5745 cfg.dir = 0;
5746 cfg.timeout = 0;
5747 if (mpt_config(ioc, &cfg) != 0)
5748 return 0;
5749
5750 if (header.PageLength == 0)
5751 return 0;
5752
5753 /* Read Header good, alloc memory
5754 */
5755 iocpage3sz = header.PageLength * 4;
5756 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5757 if (!pIoc3)
5758 return 0;
5759
5760 /* Read the Page and save the data
5761 * into malloc'd memory.
5762 */
5763 cfg.physAddr = ioc3_dma;
5764 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5765 if (mpt_config(ioc, &cfg) == 0) {
5766 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5767 if (mem) {
5768 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5769 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5770 }
5771 }
5772
5773 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5774
5775 return 0;
5776}
5777
5778static void
5779mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5780{
5781 IOCPage4_t *pIoc4;
5782 CONFIGPARMS cfg;
5783 ConfigPageHeader_t header;
5784 dma_addr_t ioc4_dma;
5785 int iocpage4sz;
5786
5787 /* Read and save IOC Page 4
5788 */
5789 header.PageVersion = 0;
5790 header.PageLength = 0;
5791 header.PageNumber = 4;
5792 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5793 cfg.cfghdr.hdr = &header;
5794 cfg.physAddr = -1;
5795 cfg.pageAddr = 0;
5796 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5797 cfg.dir = 0;
5798 cfg.timeout = 0;
5799 if (mpt_config(ioc, &cfg) != 0)
5800 return;
5801
5802 if (header.PageLength == 0)
5803 return;
5804
5805 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5806 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5807 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5808 if (!pIoc4)
5809 return;
5810 ioc->alloc_total += iocpage4sz;
5811 } else {
5812 ioc4_dma = ioc->spi_data.IocPg4_dma;
5813 iocpage4sz = ioc->spi_data.IocPg4Sz;
5814 }
5815
5816 /* Read the Page into dma memory.
5817 */
5818 cfg.physAddr = ioc4_dma;
5819 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5820 if (mpt_config(ioc, &cfg) == 0) {
5821 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5822 ioc->spi_data.IocPg4_dma = ioc4_dma;
5823 ioc->spi_data.IocPg4Sz = iocpage4sz;
5824 } else {
5825 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5826 ioc->spi_data.pIocPg4 = NULL;
5827 ioc->alloc_total -= iocpage4sz;
5828 }
5829}
5830
5831static void
5832mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5833{
5834 IOCPage1_t *pIoc1;
5835 CONFIGPARMS cfg;
5836 ConfigPageHeader_t header;
5837 dma_addr_t ioc1_dma;
5838 int iocpage1sz = 0;
5839 u32 tmp;
5840
5841 /* Check the Coalescing Timeout in IOC Page 1
5842 */
5843 header.PageVersion = 0;
5844 header.PageLength = 0;
5845 header.PageNumber = 1;
5846 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5847 cfg.cfghdr.hdr = &header;
5848 cfg.physAddr = -1;
5849 cfg.pageAddr = 0;
5850 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5851 cfg.dir = 0;
5852 cfg.timeout = 0;
5853 if (mpt_config(ioc, &cfg) != 0)
5854 return;
5855
5856 if (header.PageLength == 0)
5857 return;
5858
5859 /* Read Header good, alloc memory
5860 */
5861 iocpage1sz = header.PageLength * 4;
5862 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5863 if (!pIoc1)
5864 return;
5865
5866 /* Read the Page and check coalescing timeout
5867 */
5868 cfg.physAddr = ioc1_dma;
5869 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5870 if (mpt_config(ioc, &cfg) == 0) {
5871
5872 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5873 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5874 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5875
5876 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5877 ioc->name, tmp));
5878
5879 if (tmp > MPT_COALESCING_TIMEOUT) {
5880 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5881
5882 /* Write NVRAM and current
5883 */
5884 cfg.dir = 1;
5885 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5886 if (mpt_config(ioc, &cfg) == 0) {
5887 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5888 ioc->name, MPT_COALESCING_TIMEOUT));
5889
5890 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5891 if (mpt_config(ioc, &cfg) == 0) {
5892 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5893 "Reset NVRAM Coalescing Timeout to = %d\n",
5894 ioc->name, MPT_COALESCING_TIMEOUT));
5895 } else {
5896 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5897 "Reset NVRAM Coalescing Timeout Failed\n",
5898 ioc->name));
5899 }
5900
5901 } else {
5902 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5903 "Reset of Current Coalescing Timeout Failed!\n",
5904 ioc->name));
5905 }
5906 }
5907
5908 } else {
5909 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5910 }
5911 }
5912
5913 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5914
5915 return;
5916}
5917
5918static void
5919mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5920{
5921 CONFIGPARMS cfg;
5922 ConfigPageHeader_t hdr;
5923 dma_addr_t buf_dma;
5924 ManufacturingPage0_t *pbuf = NULL;
5925
5926 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5927 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5928
5929 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5930 cfg.cfghdr.hdr = &hdr;
5931 cfg.physAddr = -1;
5932 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5933 cfg.timeout = 10;
5934
5935 if (mpt_config(ioc, &cfg) != 0)
5936 goto out;
5937
5938 if (!cfg.cfghdr.hdr->PageLength)
5939 goto out;
5940
5941 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5942 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5943 if (!pbuf)
5944 goto out;
5945
5946 cfg.physAddr = buf_dma;
5947
5948 if (mpt_config(ioc, &cfg) != 0)
5949 goto out;
5950
5951 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5952 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5953 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5954
5955 out:
5956
5957 if (pbuf)
5958 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5959}
5960
5961/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5962/**
5963 * SendEventNotification - Send EventNotification (on or off) request to adapter
5964 * @ioc: Pointer to MPT_ADAPTER structure
5965 * @EvSwitch: Event switch flags
5966 */
5967static int
5968SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5969{
5970 EventNotification_t *evnp;
5971
5972 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5973 if (evnp == NULL) {
5974 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5975 ioc->name));
5976 return 0;
5977 }
5978 memset(evnp, 0, sizeof(*evnp));
5979
5980 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5981
5982 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5983 evnp->ChainOffset = 0;
5984 evnp->MsgFlags = 0;
5985 evnp->Switch = EvSwitch;
5986
5987 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5988
5989 return 0;
5990}
5991
5992/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5993/**
5994 * SendEventAck - Send EventAck request to MPT adapter.
5995 * @ioc: Pointer to MPT_ADAPTER structure
5996 * @evnp: Pointer to original EventNotification request
5997 */
5998static int
5999SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6000{
6001 EventAck_t *pAck;
6002
6003 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6004 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6005 ioc->name,__func__));
6006 return -1;
6007 }
6008
6009 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6010
6011 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6012 pAck->ChainOffset = 0;
6013 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6014 pAck->MsgFlags = 0;
6015 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6016 pAck->Event = evnp->Event;
6017 pAck->EventContext = evnp->EventContext;
6018
6019 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6020
6021 return 0;
6022}
6023
6024/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6025/**
6026 * mpt_config - Generic function to issue config message
6027 * @ioc: Pointer to an adapter structure
6028 * @pCfg: Pointer to a configuration structure. Struct contains
6029 * action, page address, direction, physical address
6030 * and pointer to a configuration page header
6031 * Page header is updated.
6032 *
6033 * Returns 0 for success
6034 * -EPERM if not allowed due to ISR context
6035 * -EAGAIN if no msg frames currently available
6036 * -EFAULT for non-successful reply or no reply (timeout)
6037 */
6038int
6039mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6040{
6041 Config_t *pReq;
6042 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6043 MPT_FRAME_HDR *mf;
6044 unsigned long flags;
6045 int ii, rc;
6046 int flagsLength;
6047 int in_isr;
6048
6049 /* Prevent calling wait_event() (below), if caller happens
6050 * to be in ISR context, because that is fatal!
6051 */
6052 in_isr = in_interrupt();
6053 if (in_isr) {
6054 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6055 ioc->name));
6056 return -EPERM;
6057 }
6058
6059 /* Get and Populate a free Frame
6060 */
6061 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6062 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
6063 ioc->name));
6064 return -EAGAIN;
6065 }
6066 pReq = (Config_t *)mf;
6067 pReq->Action = pCfg->action;
6068 pReq->Reserved = 0;
6069 pReq->ChainOffset = 0;
6070 pReq->Function = MPI_FUNCTION_CONFIG;
6071
6072 /* Assume page type is not extended and clear "reserved" fields. */
6073 pReq->ExtPageLength = 0;
6074 pReq->ExtPageType = 0;
6075 pReq->MsgFlags = 0;
6076
6077 for (ii=0; ii < 8; ii++)
6078 pReq->Reserved2[ii] = 0;
6079
6080 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6081 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6082 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6083 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6084
6085 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6086 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6087 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6088 pReq->ExtPageType = pExtHdr->ExtPageType;
6089 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6090
6091 /* Page Length must be treated as a reserved field for the extended header. */
6092 pReq->Header.PageLength = 0;
6093 }
6094
6095 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6096
6097 /* Add a SGE to the config request.
6098 */
6099 if (pCfg->dir)
6100 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6101 else
6102 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6103
6104 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6105 flagsLength |= pExtHdr->ExtPageLength * 4;
6106
6107 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
6108 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
6109 }
6110 else {
6111 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6112
6113 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
6114 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
6115 }
6116
6117 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6118
6119 /* Append pCfg pointer to end of mf
6120 */
6121 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
6122
6123 /* Initalize the timer
6124 */
6125 init_timer_on_stack(&pCfg->timer);
6126 pCfg->timer.data = (unsigned long) ioc;
6127 pCfg->timer.function = mpt_timer_expired;
6128 pCfg->wait_done = 0;
6129
6130 /* Set the timer; ensure 10 second minimum */
6131 if (pCfg->timeout < 10)
6132 pCfg->timer.expires = jiffies + HZ*10;
6133 else
6134 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
6135
6136 /* Add to end of Q, set timer and then issue this command */
6137 spin_lock_irqsave(&ioc->FreeQlock, flags);
6138 list_add_tail(&pCfg->linkage, &ioc->configQ);
6139 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6140
6141 add_timer(&pCfg->timer);
6142 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6143 wait_event(mpt_waitq, pCfg->wait_done);
6144
6145 /* mf has been freed - do not access */
6146
6147 rc = pCfg->status;
6148
6149 return rc;
6150}
6151
6152/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6153/**
6154 * mpt_timer_expired - Callback for timer process.
6155 * Used only internal config functionality.
6156 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
6157 */
6158static void
6159mpt_timer_expired(unsigned long data)
6160{
6161 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
6162
6163 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
6164
6165 /* Perform a FW reload */
6166 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
6167 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
6168
6169 /* No more processing.
6170 * Hard reset clean-up will wake up
6171 * process and free all resources.
6172 */
6173 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
6174
6175 return;
6176}
6177
6178/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6179/**
6180 * mpt_ioc_reset - Base cleanup for hard reset
6181 * @ioc: Pointer to the adapter structure
6182 * @reset_phase: Indicates pre- or post-reset functionality
6183 *
6184 * Remark: Frees resources with internally generated commands.
6185 */
6186static int
6187mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6188{
6189 CONFIGPARMS *pCfg;
6190 unsigned long flags;
6191
6192 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6193 ": IOC %s_reset routed to MPT base driver!\n",
6194 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
6195 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
6196
6197 if (reset_phase == MPT_IOC_SETUP_RESET) {
6198 ;
6199 } else if (reset_phase == MPT_IOC_PRE_RESET) {
6200 /* If the internal config Q is not empty -
6201 * delete timer. MF resources will be freed when
6202 * the FIFO's are primed.
6203 */
6204 spin_lock_irqsave(&ioc->FreeQlock, flags);
6205 list_for_each_entry(pCfg, &ioc->configQ, linkage)
6206 del_timer(&pCfg->timer);
6207 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6208
6209 } else {
6210 CONFIGPARMS *pNext;
6211
6212 /* Search the configQ for internal commands.
6213 * Flush the Q, and wake up all suspended threads.
6214 */
6215 spin_lock_irqsave(&ioc->FreeQlock, flags);
6216 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
6217 list_del(&pCfg->linkage);
6218
6219 pCfg->status = MPT_CONFIG_ERROR;
6220 pCfg->wait_done = 1;
6221 wake_up(&mpt_waitq);
6222 }
6223 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6224 }
6225
6226 return 1; /* currently means nothing really */
6227}
6228
6229
6230#ifdef CONFIG_PROC_FS /* { */
6231/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6232/*
6233 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6234 */
6235/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6236/**
6237 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6238 *
6239 * Returns 0 for success, non-zero for failure.
6240 */
6241static int
6242procmpt_create(void)
6243{
6244 struct proc_dir_entry *ent;
6245
6246 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6247 if (mpt_proc_root_dir == NULL)
6248 return -ENOTDIR;
6249
6250 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6251 if (ent)
6252 ent->read_proc = procmpt_summary_read;
6253
6254 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6255 if (ent)
6256 ent->read_proc = procmpt_version_read;
6257
6258 return 0;
6259}
6260
6261/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6262/**
6263 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6264 *
6265 * Returns 0 for success, non-zero for failure.
6266 */
6267static void
6268procmpt_destroy(void)
6269{
6270 remove_proc_entry("version", mpt_proc_root_dir);
6271 remove_proc_entry("summary", mpt_proc_root_dir);
6272 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6273}
6274
6275/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6276/**
6277 * procmpt_summary_read - Handle read request of a summary file
6278 * @buf: Pointer to area to write information
6279 * @start: Pointer to start pointer
6280 * @offset: Offset to start writing
6281 * @request: Amount of read data requested
6282 * @eof: Pointer to EOF integer
6283 * @data: Pointer
6284 *
6285 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6286 * Returns number of characters written to process performing the read.
6287 */
6288static int
6289procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6290{
6291 MPT_ADAPTER *ioc;
6292 char *out = buf;
6293 int len;
6294
6295 if (data) {
6296 int more = 0;
6297
6298 ioc = data;
6299 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6300
6301 out += more;
6302 } else {
6303 list_for_each_entry(ioc, &ioc_list, list) {
6304 int more = 0;
6305
6306 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6307
6308 out += more;
6309 if ((out-buf) >= request)
6310 break;
6311 }
6312 }
6313
6314 len = out - buf;
6315
6316 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6317}
6318
6319/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6320/**
6321 * procmpt_version_read - Handle read request from /proc/mpt/version.
6322 * @buf: Pointer to area to write information
6323 * @start: Pointer to start pointer
6324 * @offset: Offset to start writing
6325 * @request: Amount of read data requested
6326 * @eof: Pointer to EOF integer
6327 * @data: Pointer
6328 *
6329 * Returns number of characters written to process performing the read.
6330 */
6331static int
6332procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6333{
6334 u8 cb_idx;
6335 int scsi, fc, sas, lan, ctl, targ, dmp;
6336 char *drvname;
6337 int len;
6338
6339 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6340 len += sprintf(buf+len, " Fusion MPT base driver\n");
6341
6342 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6343 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6344 drvname = NULL;
6345 if (MptCallbacks[cb_idx]) {
6346 switch (MptDriverClass[cb_idx]) {
6347 case MPTSPI_DRIVER:
6348 if (!scsi++) drvname = "SPI host";
6349 break;
6350 case MPTFC_DRIVER:
6351 if (!fc++) drvname = "FC host";
6352 break;
6353 case MPTSAS_DRIVER:
6354 if (!sas++) drvname = "SAS host";
6355 break;
6356 case MPTLAN_DRIVER:
6357 if (!lan++) drvname = "LAN";
6358 break;
6359 case MPTSTM_DRIVER:
6360 if (!targ++) drvname = "SCSI target";
6361 break;
6362 case MPTCTL_DRIVER:
6363 if (!ctl++) drvname = "ioctl";
6364 break;
6365 }
6366
6367 if (drvname)
6368 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6369 }
6370 }
6371
6372 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6373}
6374
6375/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6376/**
6377 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6378 * @buf: Pointer to area to write information
6379 * @start: Pointer to start pointer
6380 * @offset: Offset to start writing
6381 * @request: Amount of read data requested
6382 * @eof: Pointer to EOF integer
6383 * @data: Pointer
6384 *
6385 * Returns number of characters written to process performing the read.
6386 */
6387static int
6388procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6389{
6390 MPT_ADAPTER *ioc = data;
6391 int len;
6392 char expVer[32];
6393 int sz;
6394 int p;
6395
6396 mpt_get_fw_exp_ver(expVer, ioc);
6397
6398 len = sprintf(buf, "%s:", ioc->name);
6399 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6400 len += sprintf(buf+len, " (f/w download boot flag set)");
6401// if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6402// len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6403
6404 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6405 ioc->facts.ProductID,
6406 ioc->prod_name);
6407 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6408 if (ioc->facts.FWImageSize)
6409 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6410 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6411 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6412 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6413
6414 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6415 ioc->facts.CurrentHostMfaHighAddr);
6416 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6417 ioc->facts.CurrentSenseBufferHighAddr);
6418
6419 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6420 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6421
6422 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6423 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6424 /*
6425 * Rounding UP to nearest 4-kB boundary here...
6426 */
6427 sz = (ioc->req_sz * ioc->req_depth) + 128;
6428 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6429 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6430 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6431 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6432 4*ioc->facts.RequestFrameSize,
6433 ioc->facts.GlobalCredits);
6434
6435 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6436 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6437 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6438 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6439 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6440 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6441 ioc->facts.CurReplyFrameSize,
6442 ioc->facts.ReplyQueueDepth);
6443
6444 len += sprintf(buf+len, " MaxDevices = %d\n",
6445 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6446 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6447
6448 /* per-port info */
6449 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6450 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6451 p+1,
6452 ioc->facts.NumberOfPorts);
6453 if (ioc->bus_type == FC) {
6454 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6455 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6456 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6457 a[5], a[4], a[3], a[2], a[1], a[0]);
6458 }
6459 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6460 ioc->fc_port_page0[p].WWNN.High,
6461 ioc->fc_port_page0[p].WWNN.Low,
6462 ioc->fc_port_page0[p].WWPN.High,
6463 ioc->fc_port_page0[p].WWPN.Low);
6464 }
6465 }
6466
6467 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6468}
6469
6470#endif /* CONFIG_PROC_FS } */
6471
6472/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6473static void
6474mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6475{
6476 buf[0] ='\0';
6477 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6478 sprintf(buf, " (Exp %02d%02d)",
6479 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6480 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6481
6482 /* insider hack! */
6483 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6484 strcat(buf, " [MDBG]");
6485 }
6486}
6487
6488/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6489/**
6490 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6491 * @ioc: Pointer to MPT_ADAPTER structure
6492 * @buffer: Pointer to buffer where IOC summary info should be written
6493 * @size: Pointer to number of bytes we wrote (set by this routine)
6494 * @len: Offset at which to start writing in buffer
6495 * @showlan: Display LAN stuff?
6496 *
6497 * This routine writes (english readable) ASCII text, which represents
6498 * a summary of IOC information, to a buffer.
6499 */
6500void
6501mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6502{
6503 char expVer[32];
6504 int y;
6505
6506 mpt_get_fw_exp_ver(expVer, ioc);
6507
6508 /*
6509 * Shorter summary of attached ioc's...
6510 */
6511 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6512 ioc->name,
6513 ioc->prod_name,
6514 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6515 ioc->facts.FWVersion.Word,
6516 expVer,
6517 ioc->facts.NumberOfPorts,
6518 ioc->req_depth);
6519
6520 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6521 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6522 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6523 a[5], a[4], a[3], a[2], a[1], a[0]);
6524 }
6525
6526 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6527
6528 if (!ioc->active)
6529 y += sprintf(buffer+len+y, " (disabled)");
6530
6531 y += sprintf(buffer+len+y, "\n");
6532
6533 *size = y;
6534}
6535
6536
6537/**
6538 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6539 * the kernel
6540 * @ioc: Pointer to MPT_ADAPTER structure
6541 *
6542 **/
6543void
6544mpt_halt_firmware(MPT_ADAPTER *ioc)
6545{
6546 u32 ioc_raw_state;
6547
6548 ioc_raw_state = mpt_GetIocState(ioc, 0);
6549
6550 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6551 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6552 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6553 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6554 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6555 } else {
6556 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6557 panic("%s: Firmware is halted due to command timeout\n",
6558 ioc->name);
6559 }
6560}
6561EXPORT_SYMBOL(mpt_halt_firmware);
6562
6563/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6564/*
6565 * Reset Handling
6566 */
6567/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6568/**
6569 * mpt_HardResetHandler - Generic reset handler
6570 * @ioc: Pointer to MPT_ADAPTER structure
6571 * @sleepFlag: Indicates if sleep or schedule must be called.
6572 *
6573 * Issues SCSI Task Management call based on input arg values.
6574 * If TaskMgmt fails, returns associated SCSI request.
6575 *
6576 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6577 * or a non-interrupt thread. In the former, must not call schedule().
6578 *
6579 * Note: A return of -1 is a FATAL error case, as it means a
6580 * FW reload/initialization failed.
6581 *
6582 * Returns 0 for SUCCESS or -1 if FAILED.
6583 */
6584int
6585mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6586{
6587 int rc;
6588 unsigned long flags;
6589
6590 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6591#ifdef MFCNT
6592 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6593 printk("MF count 0x%x !\n", ioc->mfcnt);
6594#endif
6595 if (mpt_fwfault_debug)
6596 mpt_halt_firmware(ioc);
6597
6598 /* Reset the adapter. Prevent more than 1 call to
6599 * mpt_do_ioc_recovery at any instant in time.
6600 */
6601 spin_lock_irqsave(&ioc->diagLock, flags);
6602 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6603 spin_unlock_irqrestore(&ioc->diagLock, flags);
6604 return 0;
6605 } else {
6606 ioc->diagPending = 1;
6607 }
6608 spin_unlock_irqrestore(&ioc->diagLock, flags);
6609
6610 /* FIXME: If do_ioc_recovery fails, repeat....
6611 */
6612
6613 /* The SCSI driver needs to adjust timeouts on all current
6614 * commands prior to the diagnostic reset being issued.
6615 * Prevents timeouts occurring during a diagnostic reset...very bad.
6616 * For all other protocol drivers, this is a no-op.
6617 */
6618 {
6619 u8 cb_idx;
6620 int r = 0;
6621
6622 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6623 if (MptResetHandlers[cb_idx]) {
6624 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6625 ioc->name, cb_idx));
6626 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6627 if (ioc->alt_ioc) {
6628 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6629 ioc->name, ioc->alt_ioc->name, cb_idx));
6630 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6631 }
6632 }
6633 }
6634 }
6635
6636 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6637 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6638 }
6639 ioc->reload_fw = 0;
6640 if (ioc->alt_ioc)
6641 ioc->alt_ioc->reload_fw = 0;
6642
6643 spin_lock_irqsave(&ioc->diagLock, flags);
6644 ioc->diagPending = 0;
6645 if (ioc->alt_ioc)
6646 ioc->alt_ioc->diagPending = 0;
6647 spin_unlock_irqrestore(&ioc->diagLock, flags);
6648
6649 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6650
6651 return rc;
6652}
6653
6654/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6655static void
6656EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6657{
6658 char *ds = NULL;
6659
6660 switch(event) {
6661 case MPI_EVENT_NONE:
6662 ds = "None";
6663 break;
6664 case MPI_EVENT_LOG_DATA:
6665 ds = "Log Data";
6666 break;
6667 case MPI_EVENT_STATE_CHANGE:
6668 ds = "State Change";
6669 break;
6670 case MPI_EVENT_UNIT_ATTENTION:
6671 ds = "Unit Attention";
6672 break;
6673 case MPI_EVENT_IOC_BUS_RESET:
6674 ds = "IOC Bus Reset";
6675 break;
6676 case MPI_EVENT_EXT_BUS_RESET:
6677 ds = "External Bus Reset";
6678 break;
6679 case MPI_EVENT_RESCAN:
6680 ds = "Bus Rescan Event";
6681 break;
6682 case MPI_EVENT_LINK_STATUS_CHANGE:
6683 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6684 ds = "Link Status(FAILURE) Change";
6685 else
6686 ds = "Link Status(ACTIVE) Change";
6687 break;
6688 case MPI_EVENT_LOOP_STATE_CHANGE:
6689 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6690 ds = "Loop State(LIP) Change";
6691 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6692 ds = "Loop State(LPE) Change"; /* ??? */
6693 else
6694 ds = "Loop State(LPB) Change"; /* ??? */
6695 break;
6696 case MPI_EVENT_LOGOUT:
6697 ds = "Logout";
6698 break;
6699 case MPI_EVENT_EVENT_CHANGE:
6700 if (evData0)
6701 ds = "Events ON";
6702 else
6703 ds = "Events OFF";
6704 break;
6705 case MPI_EVENT_INTEGRATED_RAID:
6706 {
6707 u8 ReasonCode = (u8)(evData0 >> 16);
6708 switch (ReasonCode) {
6709 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6710 ds = "Integrated Raid: Volume Created";
6711 break;
6712 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6713 ds = "Integrated Raid: Volume Deleted";
6714 break;
6715 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6716 ds = "Integrated Raid: Volume Settings Changed";
6717 break;
6718 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6719 ds = "Integrated Raid: Volume Status Changed";
6720 break;
6721 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6722 ds = "Integrated Raid: Volume Physdisk Changed";
6723 break;
6724 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6725 ds = "Integrated Raid: Physdisk Created";
6726 break;
6727 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6728 ds = "Integrated Raid: Physdisk Deleted";
6729 break;
6730 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6731 ds = "Integrated Raid: Physdisk Settings Changed";
6732 break;
6733 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6734 ds = "Integrated Raid: Physdisk Status Changed";
6735 break;
6736 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6737 ds = "Integrated Raid: Domain Validation Needed";
6738 break;
6739 case MPI_EVENT_RAID_RC_SMART_DATA :
6740 ds = "Integrated Raid; Smart Data";
6741 break;
6742 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6743 ds = "Integrated Raid: Replace Action Started";
6744 break;
6745 default:
6746 ds = "Integrated Raid";
6747 break;
6748 }
6749 break;
6750 }
6751 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6752 ds = "SCSI Device Status Change";
6753 break;
6754 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6755 {
6756 u8 id = (u8)(evData0);
6757 u8 channel = (u8)(evData0 >> 8);
6758 u8 ReasonCode = (u8)(evData0 >> 16);
6759 switch (ReasonCode) {
6760 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6761 snprintf(evStr, EVENT_DESCR_STR_SZ,
6762 "SAS Device Status Change: Added: "
6763 "id=%d channel=%d", id, channel);
6764 break;
6765 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6766 snprintf(evStr, EVENT_DESCR_STR_SZ,
6767 "SAS Device Status Change: Deleted: "
6768 "id=%d channel=%d", id, channel);
6769 break;
6770 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6771 snprintf(evStr, EVENT_DESCR_STR_SZ,
6772 "SAS Device Status Change: SMART Data: "
6773 "id=%d channel=%d", id, channel);
6774 break;
6775 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6776 snprintf(evStr, EVENT_DESCR_STR_SZ,
6777 "SAS Device Status Change: No Persistancy: "
6778 "id=%d channel=%d", id, channel);
6779 break;
6780 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6781 snprintf(evStr, EVENT_DESCR_STR_SZ,
6782 "SAS Device Status Change: Unsupported Device "
6783 "Discovered : id=%d channel=%d", id, channel);
6784 break;
6785 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6786 snprintf(evStr, EVENT_DESCR_STR_SZ,
6787 "SAS Device Status Change: Internal Device "
6788 "Reset : id=%d channel=%d", id, channel);
6789 break;
6790 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6791 snprintf(evStr, EVENT_DESCR_STR_SZ,
6792 "SAS Device Status Change: Internal Task "
6793 "Abort : id=%d channel=%d", id, channel);
6794 break;
6795 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6796 snprintf(evStr, EVENT_DESCR_STR_SZ,
6797 "SAS Device Status Change: Internal Abort "
6798 "Task Set : id=%d channel=%d", id, channel);
6799 break;
6800 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6801 snprintf(evStr, EVENT_DESCR_STR_SZ,
6802 "SAS Device Status Change: Internal Clear "
6803 "Task Set : id=%d channel=%d", id, channel);
6804 break;
6805 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6806 snprintf(evStr, EVENT_DESCR_STR_SZ,
6807 "SAS Device Status Change: Internal Query "
6808 "Task : id=%d channel=%d", id, channel);
6809 break;
6810 default:
6811 snprintf(evStr, EVENT_DESCR_STR_SZ,
6812 "SAS Device Status Change: Unknown: "
6813 "id=%d channel=%d", id, channel);
6814 break;
6815 }
6816 break;
6817 }
6818 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6819 ds = "Bus Timer Expired";
6820 break;
6821 case MPI_EVENT_QUEUE_FULL:
6822 {
6823 u16 curr_depth = (u16)(evData0 >> 16);
6824 u8 channel = (u8)(evData0 >> 8);
6825 u8 id = (u8)(evData0);
6826
6827 snprintf(evStr, EVENT_DESCR_STR_SZ,
6828 "Queue Full: channel=%d id=%d depth=%d",
6829 channel, id, curr_depth);
6830 break;
6831 }
6832 case MPI_EVENT_SAS_SES:
6833 ds = "SAS SES Event";
6834 break;
6835 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6836 ds = "Persistent Table Full";
6837 break;
6838 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6839 {
6840 u8 LinkRates = (u8)(evData0 >> 8);
6841 u8 PhyNumber = (u8)(evData0);
6842 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6843 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6844 switch (LinkRates) {
6845 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6846 snprintf(evStr, EVENT_DESCR_STR_SZ,
6847 "SAS PHY Link Status: Phy=%d:"
6848 " Rate Unknown",PhyNumber);
6849 break;
6850 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6851 snprintf(evStr, EVENT_DESCR_STR_SZ,
6852 "SAS PHY Link Status: Phy=%d:"
6853 " Phy Disabled",PhyNumber);
6854 break;
6855 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6856 snprintf(evStr, EVENT_DESCR_STR_SZ,
6857 "SAS PHY Link Status: Phy=%d:"
6858 " Failed Speed Nego",PhyNumber);
6859 break;
6860 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6861 snprintf(evStr, EVENT_DESCR_STR_SZ,
6862 "SAS PHY Link Status: Phy=%d:"
6863 " Sata OOB Completed",PhyNumber);
6864 break;
6865 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6866 snprintf(evStr, EVENT_DESCR_STR_SZ,
6867 "SAS PHY Link Status: Phy=%d:"
6868 " Rate 1.5 Gbps",PhyNumber);
6869 break;
6870 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6871 snprintf(evStr, EVENT_DESCR_STR_SZ,
6872 "SAS PHY Link Status: Phy=%d:"
6873 " Rate 3.0 Gpbs",PhyNumber);
6874 break;
6875 default:
6876 snprintf(evStr, EVENT_DESCR_STR_SZ,
6877 "SAS PHY Link Status: Phy=%d", PhyNumber);
6878 break;
6879 }
6880 break;
6881 }
6882 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6883 ds = "SAS Discovery Error";
6884 break;
6885 case MPI_EVENT_IR_RESYNC_UPDATE:
6886 {
6887 u8 resync_complete = (u8)(evData0 >> 16);
6888 snprintf(evStr, EVENT_DESCR_STR_SZ,
6889 "IR Resync Update: Complete = %d:",resync_complete);
6890 break;
6891 }
6892 case MPI_EVENT_IR2:
6893 {
6894 u8 ReasonCode = (u8)(evData0 >> 16);
6895 switch (ReasonCode) {
6896 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6897 ds = "IR2: LD State Changed";
6898 break;
6899 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6900 ds = "IR2: PD State Changed";
6901 break;
6902 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6903 ds = "IR2: Bad Block Table Full";
6904 break;
6905 case MPI_EVENT_IR2_RC_PD_INSERTED:
6906 ds = "IR2: PD Inserted";
6907 break;
6908 case MPI_EVENT_IR2_RC_PD_REMOVED:
6909 ds = "IR2: PD Removed";
6910 break;
6911 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6912 ds = "IR2: Foreign CFG Detected";
6913 break;
6914 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6915 ds = "IR2: Rebuild Medium Error";
6916 break;
6917 default:
6918 ds = "IR2";
6919 break;
6920 }
6921 break;
6922 }
6923 case MPI_EVENT_SAS_DISCOVERY:
6924 {
6925 if (evData0)
6926 ds = "SAS Discovery: Start";
6927 else
6928 ds = "SAS Discovery: Stop";
6929 break;
6930 }
6931 case MPI_EVENT_LOG_ENTRY_ADDED:
6932 ds = "SAS Log Entry Added";
6933 break;
6934
6935 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6936 {
6937 u8 phy_num = (u8)(evData0);
6938 u8 port_num = (u8)(evData0 >> 8);
6939 u8 port_width = (u8)(evData0 >> 16);
6940 u8 primative = (u8)(evData0 >> 24);
6941 snprintf(evStr, EVENT_DESCR_STR_SZ,
6942 "SAS Broadcase Primative: phy=%d port=%d "
6943 "width=%d primative=0x%02x",
6944 phy_num, port_num, port_width, primative);
6945 break;
6946 }
6947
6948 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6949 {
6950 u8 reason = (u8)(evData0);
6951 u8 port_num = (u8)(evData0 >> 8);
6952 u16 handle = le16_to_cpu(evData0 >> 16);
6953
6954 snprintf(evStr, EVENT_DESCR_STR_SZ,
6955 "SAS Initiator Device Status Change: reason=0x%02x "
6956 "port=%d handle=0x%04x",
6957 reason, port_num, handle);
6958 break;
6959 }
6960
6961 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6962 {
6963 u8 max_init = (u8)(evData0);
6964 u8 current_init = (u8)(evData0 >> 8);
6965
6966 snprintf(evStr, EVENT_DESCR_STR_SZ,
6967 "SAS Initiator Device Table Overflow: max initiators=%02d "
6968 "current initators=%02d",
6969 max_init, current_init);
6970 break;
6971 }
6972 case MPI_EVENT_SAS_SMP_ERROR:
6973 {
6974 u8 status = (u8)(evData0);
6975 u8 port_num = (u8)(evData0 >> 8);
6976 u8 result = (u8)(evData0 >> 16);
6977
6978 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6979 snprintf(evStr, EVENT_DESCR_STR_SZ,
6980 "SAS SMP Error: port=%d result=0x%02x",
6981 port_num, result);
6982 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6983 snprintf(evStr, EVENT_DESCR_STR_SZ,
6984 "SAS SMP Error: port=%d : CRC Error",
6985 port_num);
6986 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6987 snprintf(evStr, EVENT_DESCR_STR_SZ,
6988 "SAS SMP Error: port=%d : Timeout",
6989 port_num);
6990 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6991 snprintf(evStr, EVENT_DESCR_STR_SZ,
6992 "SAS SMP Error: port=%d : No Destination",
6993 port_num);
6994 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6995 snprintf(evStr, EVENT_DESCR_STR_SZ,
6996 "SAS SMP Error: port=%d : Bad Destination",
6997 port_num);
6998 else
6999 snprintf(evStr, EVENT_DESCR_STR_SZ,
7000 "SAS SMP Error: port=%d : status=0x%02x",
7001 port_num, status);
7002 break;
7003 }
7004
7005 /*
7006 * MPT base "custom" events may be added here...
7007 */
7008 default:
7009 ds = "Unknown";
7010 break;
7011 }
7012 if (ds)
7013 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7014}
7015
7016/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7017/**
7018 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7019 * @ioc: Pointer to MPT_ADAPTER structure
7020 * @pEventReply: Pointer to EventNotification reply frame
7021 * @evHandlers: Pointer to integer, number of event handlers
7022 *
7023 * Routes a received EventNotificationReply to all currently registered
7024 * event handlers.
7025 * Returns sum of event handlers return values.
7026 */
7027static int
7028ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7029{
7030 u16 evDataLen;
7031 u32 evData0 = 0;
7032// u32 evCtx;
7033 int ii;
7034 u8 cb_idx;
7035 int r = 0;
7036 int handlers = 0;
7037 char evStr[EVENT_DESCR_STR_SZ];
7038 u8 event;
7039
7040 /*
7041 * Do platform normalization of values
7042 */
7043 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7044// evCtx = le32_to_cpu(pEventReply->EventContext);
7045 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7046 if (evDataLen) {
7047 evData0 = le32_to_cpu(pEventReply->Data[0]);
7048 }
7049
7050 EventDescriptionStr(event, evData0, evStr);
7051 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
7052 ioc->name,
7053 event,
7054 evStr));
7055
7056#ifdef CONFIG_FUSION_LOGGING
7057 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7058 ": Event data:\n", ioc->name));
7059 for (ii = 0; ii < evDataLen; ii++)
7060 devtverboseprintk(ioc, printk(" %08x",
7061 le32_to_cpu(pEventReply->Data[ii])));
7062 devtverboseprintk(ioc, printk("\n"));
7063#endif
7064
7065 /*
7066 * Do general / base driver event processing
7067 */
7068 switch(event) {
7069 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7070 if (evDataLen) {
7071 u8 evState = evData0 & 0xFF;
7072
7073 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7074
7075 /* Update EventState field in cached IocFacts */
7076 if (ioc->facts.Function) {
7077 ioc->facts.EventState = evState;
7078 }
7079 }
7080 break;
7081 case MPI_EVENT_INTEGRATED_RAID:
7082 mptbase_raid_process_event_data(ioc,
7083 (MpiEventDataRaid_t *)pEventReply->Data);
7084 break;
7085 default:
7086 break;
7087 }
7088
7089 /*
7090 * Should this event be logged? Events are written sequentially.
7091 * When buffer is full, start again at the top.
7092 */
7093 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7094 int idx;
7095
7096 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7097
7098 ioc->events[idx].event = event;
7099 ioc->events[idx].eventContext = ioc->eventContext;
7100
7101 for (ii = 0; ii < 2; ii++) {
7102 if (ii < evDataLen)
7103 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7104 else
7105 ioc->events[idx].data[ii] = 0;
7106 }
7107
7108 ioc->eventContext++;
7109 }
7110
7111
7112 /*
7113 * Call each currently registered protocol event handler.
7114 */
7115 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7116 if (MptEvHandlers[cb_idx]) {
7117 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
7118 ioc->name, cb_idx));
7119 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7120 handlers++;
7121 }
7122 }
7123 /* FIXME? Examine results here? */
7124
7125 /*
7126 * If needed, send (a single) EventAck.
7127 */
7128 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7129 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7130 "EventAck required\n",ioc->name));
7131 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7132 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7133 ioc->name, ii));
7134 }
7135 }
7136
7137 *evHandlers = handlers;
7138 return r;
7139}
7140
7141/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7142/**
7143 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7144 * @ioc: Pointer to MPT_ADAPTER structure
7145 * @log_info: U32 LogInfo reply word from the IOC
7146 *
7147 * Refer to lsi/mpi_log_fc.h.
7148 */
7149static void
7150mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7151{
7152 char *desc = "unknown";
7153
7154 switch (log_info & 0xFF000000) {
7155 case MPI_IOCLOGINFO_FC_INIT_BASE:
7156 desc = "FCP Initiator";
7157 break;
7158 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7159 desc = "FCP Target";
7160 break;
7161 case MPI_IOCLOGINFO_FC_LAN_BASE:
7162 desc = "LAN";
7163 break;
7164 case MPI_IOCLOGINFO_FC_MSG_BASE:
7165 desc = "MPI Message Layer";
7166 break;
7167 case MPI_IOCLOGINFO_FC_LINK_BASE:
7168 desc = "FC Link";
7169 break;
7170 case MPI_IOCLOGINFO_FC_CTX_BASE:
7171 desc = "Context Manager";
7172 break;
7173 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7174 desc = "Invalid Field Offset";
7175 break;
7176 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7177 desc = "State Change Info";
7178 break;
7179 }
7180
7181 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7182 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7183}
7184
7185/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7186/**
7187 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7188 * @ioc: Pointer to MPT_ADAPTER structure
7189 * @log_info: U32 LogInfo word from the IOC
7190 *
7191 * Refer to lsi/sp_log.h.
7192 */
7193static void
7194mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7195{
7196 u32 info = log_info & 0x00FF0000;
7197 char *desc = "unknown";
7198
7199 switch (info) {
7200 case 0x00010000:
7201 desc = "bug! MID not found";
7202 if (ioc->reload_fw == 0)
7203 ioc->reload_fw++;
7204 break;
7205
7206 case 0x00020000:
7207 desc = "Parity Error";
7208 break;
7209
7210 case 0x00030000:
7211 desc = "ASYNC Outbound Overrun";
7212 break;
7213
7214 case 0x00040000:
7215 desc = "SYNC Offset Error";
7216 break;
7217
7218 case 0x00050000:
7219 desc = "BM Change";
7220 break;
7221
7222 case 0x00060000:
7223 desc = "Msg In Overflow";
7224 break;
7225
7226 case 0x00070000:
7227 desc = "DMA Error";
7228 break;
7229
7230 case 0x00080000:
7231 desc = "Outbound DMA Overrun";
7232 break;
7233
7234 case 0x00090000:
7235 desc = "Task Management";
7236 break;
7237
7238 case 0x000A0000:
7239 desc = "Device Problem";
7240 break;
7241
7242 case 0x000B0000:
7243 desc = "Invalid Phase Change";
7244 break;
7245
7246 case 0x000C0000:
7247 desc = "Untagged Table Size";
7248 break;
7249
7250 }
7251
7252 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7253}
7254
7255/* strings for sas loginfo */
7256 static char *originator_str[] = {
7257 "IOP", /* 00h */
7258 "PL", /* 01h */
7259 "IR" /* 02h */
7260 };
7261 static char *iop_code_str[] = {
7262 NULL, /* 00h */
7263 "Invalid SAS Address", /* 01h */
7264 NULL, /* 02h */
7265 "Invalid Page", /* 03h */
7266 "Diag Message Error", /* 04h */
7267 "Task Terminated", /* 05h */
7268 "Enclosure Management", /* 06h */
7269 "Target Mode" /* 07h */
7270 };
7271 static char *pl_code_str[] = {
7272 NULL, /* 00h */
7273 "Open Failure", /* 01h */
7274 "Invalid Scatter Gather List", /* 02h */
7275 "Wrong Relative Offset or Frame Length", /* 03h */
7276 "Frame Transfer Error", /* 04h */
7277 "Transmit Frame Connected Low", /* 05h */
7278 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7279 "SATA Read Log Receive Data Error", /* 07h */
7280 "SATA NCQ Fail All Commands After Error", /* 08h */
7281 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7282 "Receive Frame Invalid Message", /* 0Ah */
7283 "Receive Context Message Valid Error", /* 0Bh */
7284 "Receive Frame Current Frame Error", /* 0Ch */
7285 "SATA Link Down", /* 0Dh */
7286 "Discovery SATA Init W IOS", /* 0Eh */
7287 "Config Invalid Page", /* 0Fh */
7288 "Discovery SATA Init Timeout", /* 10h */
7289 "Reset", /* 11h */
7290 "Abort", /* 12h */
7291 "IO Not Yet Executed", /* 13h */
7292 "IO Executed", /* 14h */
7293 "Persistent Reservation Out Not Affiliation "
7294 "Owner", /* 15h */
7295 "Open Transmit DMA Abort", /* 16h */
7296 "IO Device Missing Delay Retry", /* 17h */
7297 "IO Cancelled Due to Recieve Error", /* 18h */
7298 NULL, /* 19h */
7299 NULL, /* 1Ah */
7300 NULL, /* 1Bh */
7301 NULL, /* 1Ch */
7302 NULL, /* 1Dh */
7303 NULL, /* 1Eh */
7304 NULL, /* 1Fh */
7305 "Enclosure Management" /* 20h */
7306 };
7307 static char *ir_code_str[] = {
7308 "Raid Action Error", /* 00h */
7309 NULL, /* 00h */
7310 NULL, /* 01h */
7311 NULL, /* 02h */
7312 NULL, /* 03h */
7313 NULL, /* 04h */
7314 NULL, /* 05h */
7315 NULL, /* 06h */
7316 NULL /* 07h */
7317 };
7318 static char *raid_sub_code_str[] = {
7319 NULL, /* 00h */
7320 "Volume Creation Failed: Data Passed too "
7321 "Large", /* 01h */
7322 "Volume Creation Failed: Duplicate Volumes "
7323 "Attempted", /* 02h */
7324 "Volume Creation Failed: Max Number "
7325 "Supported Volumes Exceeded", /* 03h */
7326 "Volume Creation Failed: DMA Error", /* 04h */
7327 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7328 "Volume Creation Failed: Error Reading "
7329 "MFG Page 4", /* 06h */
7330 "Volume Creation Failed: Creating Internal "
7331 "Structures", /* 07h */
7332 NULL, /* 08h */
7333 NULL, /* 09h */
7334 NULL, /* 0Ah */
7335 NULL, /* 0Bh */
7336 NULL, /* 0Ch */
7337 NULL, /* 0Dh */
7338 NULL, /* 0Eh */
7339 NULL, /* 0Fh */
7340 "Activation failed: Already Active Volume", /* 10h */
7341 "Activation failed: Unsupported Volume Type", /* 11h */
7342 "Activation failed: Too Many Active Volumes", /* 12h */
7343 "Activation failed: Volume ID in Use", /* 13h */
7344 "Activation failed: Reported Failure", /* 14h */
7345 "Activation failed: Importing a Volume", /* 15h */
7346 NULL, /* 16h */
7347 NULL, /* 17h */
7348 NULL, /* 18h */
7349 NULL, /* 19h */
7350 NULL, /* 1Ah */
7351 NULL, /* 1Bh */
7352 NULL, /* 1Ch */
7353 NULL, /* 1Dh */
7354 NULL, /* 1Eh */
7355 NULL, /* 1Fh */
7356 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7357 "Phys Disk failed: Data Passed too Large", /* 21h */
7358 "Phys Disk failed: DMA Error", /* 22h */
7359 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7360 "Phys Disk failed: Creating Phys Disk Config "
7361 "Page", /* 24h */
7362 NULL, /* 25h */
7363 NULL, /* 26h */
7364 NULL, /* 27h */
7365 NULL, /* 28h */
7366 NULL, /* 29h */
7367 NULL, /* 2Ah */
7368 NULL, /* 2Bh */
7369 NULL, /* 2Ch */
7370 NULL, /* 2Dh */
7371 NULL, /* 2Eh */
7372 NULL, /* 2Fh */
7373 "Compatibility Error: IR Disabled", /* 30h */
7374 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7375 "Compatibility Error: Device not Direct Access "
7376 "Device ", /* 32h */
7377 "Compatibility Error: Removable Device Found", /* 33h */
7378 "Compatibility Error: Device SCSI Version not "
7379 "2 or Higher", /* 34h */
7380 "Compatibility Error: SATA Device, 48 BIT LBA "
7381 "not Supported", /* 35h */
7382 "Compatibility Error: Device doesn't have "
7383 "512 Byte Block Sizes", /* 36h */
7384 "Compatibility Error: Volume Type Check Failed", /* 37h */
7385 "Compatibility Error: Volume Type is "
7386 "Unsupported by FW", /* 38h */
7387 "Compatibility Error: Disk Drive too Small for "
7388 "use in Volume", /* 39h */
7389 "Compatibility Error: Phys Disk for Create "
7390 "Volume not Found", /* 3Ah */
7391 "Compatibility Error: Too Many or too Few "
7392 "Disks for Volume Type", /* 3Bh */
7393 "Compatibility Error: Disk stripe Sizes "
7394 "Must be 64KB", /* 3Ch */
7395 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7396 };
7397
7398/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7399/**
7400 * mpt_sas_log_info - Log information returned from SAS IOC.
7401 * @ioc: Pointer to MPT_ADAPTER structure
7402 * @log_info: U32 LogInfo reply word from the IOC
7403 *
7404 * Refer to lsi/mpi_log_sas.h.
7405 **/
7406static void
7407mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7408{
7409union loginfo_type {
7410 u32 loginfo;
7411 struct {
7412 u32 subcode:16;
7413 u32 code:8;
7414 u32 originator:4;
7415 u32 bus_type:4;
7416 }dw;
7417};
7418 union loginfo_type sas_loginfo;
7419 char *originator_desc = NULL;
7420 char *code_desc = NULL;
7421 char *sub_code_desc = NULL;
7422
7423 sas_loginfo.loginfo = log_info;
7424 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7425 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
7426 return;
7427
7428 originator_desc = originator_str[sas_loginfo.dw.originator];
7429
7430 switch (sas_loginfo.dw.originator) {
7431
7432 case 0: /* IOP */
7433 if (sas_loginfo.dw.code <
7434 ARRAY_SIZE(iop_code_str))
7435 code_desc = iop_code_str[sas_loginfo.dw.code];
7436 break;
7437 case 1: /* PL */
7438 if (sas_loginfo.dw.code <
7439 ARRAY_SIZE(pl_code_str))
7440 code_desc = pl_code_str[sas_loginfo.dw.code];
7441 break;
7442 case 2: /* IR */
7443 if (sas_loginfo.dw.code >=
7444 ARRAY_SIZE(ir_code_str))
7445 break;
7446 code_desc = ir_code_str[sas_loginfo.dw.code];
7447 if (sas_loginfo.dw.subcode >=
7448 ARRAY_SIZE(raid_sub_code_str))
7449 break;
7450 if (sas_loginfo.dw.code == 0)
7451 sub_code_desc =
7452 raid_sub_code_str[sas_loginfo.dw.subcode];
7453 break;
7454 default:
7455 return;
7456 }
7457
7458 if (sub_code_desc != NULL)
7459 printk(MYIOC_s_INFO_FMT
7460 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7461 " SubCode={%s}\n",
7462 ioc->name, log_info, originator_desc, code_desc,
7463 sub_code_desc);
7464 else if (code_desc != NULL)
7465 printk(MYIOC_s_INFO_FMT
7466 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7467 " SubCode(0x%04x)\n",
7468 ioc->name, log_info, originator_desc, code_desc,
7469 sas_loginfo.dw.subcode);
7470 else
7471 printk(MYIOC_s_INFO_FMT
7472 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7473 " SubCode(0x%04x)\n",
7474 ioc->name, log_info, originator_desc,
7475 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7476}
7477
7478/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7479/**
7480 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7481 * @ioc: Pointer to MPT_ADAPTER structure
7482 * @ioc_status: U32 IOCStatus word from IOC
7483 * @mf: Pointer to MPT request frame
7484 *
7485 * Refer to lsi/mpi.h.
7486 **/
7487static void
7488mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7489{
7490 Config_t *pReq = (Config_t *)mf;
7491 char extend_desc[EVENT_DESCR_STR_SZ];
7492 char *desc = NULL;
7493 u32 form;
7494 u8 page_type;
7495
7496 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7497 page_type = pReq->ExtPageType;
7498 else
7499 page_type = pReq->Header.PageType;
7500
7501 /*
7502 * ignore invalid page messages for GET_NEXT_HANDLE
7503 */
7504 form = le32_to_cpu(pReq->PageAddress);
7505 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7506 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7507 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7508 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7509 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7510 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7511 return;
7512 }
7513 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7514 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7515 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7516 return;
7517 }
7518
7519 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7520 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7521 page_type, pReq->Header.PageNumber, pReq->Action, form);
7522
7523 switch (ioc_status) {
7524
7525 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7526 desc = "Config Page Invalid Action";
7527 break;
7528
7529 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7530 desc = "Config Page Invalid Type";
7531 break;
7532
7533 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7534 desc = "Config Page Invalid Page";
7535 break;
7536
7537 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7538 desc = "Config Page Invalid Data";
7539 break;
7540
7541 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7542 desc = "Config Page No Defaults";
7543 break;
7544
7545 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7546 desc = "Config Page Can't Commit";
7547 break;
7548 }
7549
7550 if (!desc)
7551 return;
7552
7553 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7554 ioc->name, ioc_status, desc, extend_desc));
7555}
7556
7557/**
7558 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7559 * @ioc: Pointer to MPT_ADAPTER structure
7560 * @ioc_status: U32 IOCStatus word from IOC
7561 * @mf: Pointer to MPT request frame
7562 *
7563 * Refer to lsi/mpi.h.
7564 **/
7565static void
7566mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7567{
7568 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7569 char *desc = NULL;
7570
7571 switch (status) {
7572
7573/****************************************************************************/
7574/* Common IOCStatus values for all replies */
7575/****************************************************************************/
7576
7577 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7578 desc = "Invalid Function";
7579 break;
7580
7581 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7582 desc = "Busy";
7583 break;
7584
7585 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7586 desc = "Invalid SGL";
7587 break;
7588
7589 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7590 desc = "Internal Error";
7591 break;
7592
7593 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7594 desc = "Reserved";
7595 break;
7596
7597 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7598 desc = "Insufficient Resources";
7599 break;
7600
7601 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7602 desc = "Invalid Field";
7603 break;
7604
7605 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7606 desc = "Invalid State";
7607 break;
7608
7609/****************************************************************************/
7610/* Config IOCStatus values */
7611/****************************************************************************/
7612
7613 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7614 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7615 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7616 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7617 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7618 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7619 mpt_iocstatus_info_config(ioc, status, mf);
7620 break;
7621
7622/****************************************************************************/
7623/* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7624/* */
7625/* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7626/* */
7627/****************************************************************************/
7628
7629 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7630 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7631 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7632 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7633 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7634 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7635 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7636 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7637 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7638 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7639 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7640 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7641 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7642 break;
7643
7644/****************************************************************************/
7645/* SCSI Target values */
7646/****************************************************************************/
7647
7648 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7649 desc = "Target: Priority IO";
7650 break;
7651
7652 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7653 desc = "Target: Invalid Port";
7654 break;
7655
7656 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7657 desc = "Target Invalid IO Index:";
7658 break;
7659
7660 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7661 desc = "Target: Aborted";
7662 break;
7663
7664 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7665 desc = "Target: No Conn Retryable";
7666 break;
7667
7668 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7669 desc = "Target: No Connection";
7670 break;
7671
7672 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7673 desc = "Target: Transfer Count Mismatch";
7674 break;
7675
7676 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7677 desc = "Target: STS Data not Sent";
7678 break;
7679
7680 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7681 desc = "Target: Data Offset Error";
7682 break;
7683
7684 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7685 desc = "Target: Too Much Write Data";
7686 break;
7687
7688 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7689 desc = "Target: IU Too Short";
7690 break;
7691
7692 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7693 desc = "Target: ACK NAK Timeout";
7694 break;
7695
7696 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7697 desc = "Target: Nak Received";
7698 break;
7699
7700/****************************************************************************/
7701/* Fibre Channel Direct Access values */
7702/****************************************************************************/
7703
7704 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7705 desc = "FC: Aborted";
7706 break;
7707
7708 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7709 desc = "FC: RX ID Invalid";
7710 break;
7711
7712 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7713 desc = "FC: DID Invalid";
7714 break;
7715
7716 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7717 desc = "FC: Node Logged Out";
7718 break;
7719
7720 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7721 desc = "FC: Exchange Canceled";
7722 break;
7723
7724/****************************************************************************/
7725/* LAN values */
7726/****************************************************************************/
7727
7728 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7729 desc = "LAN: Device not Found";
7730 break;
7731
7732 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7733 desc = "LAN: Device Failure";
7734 break;
7735
7736 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7737 desc = "LAN: Transmit Error";
7738 break;
7739
7740 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7741 desc = "LAN: Transmit Aborted";
7742 break;
7743
7744 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7745 desc = "LAN: Receive Error";
7746 break;
7747
7748 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7749 desc = "LAN: Receive Aborted";
7750 break;
7751
7752 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7753 desc = "LAN: Partial Packet";
7754 break;
7755
7756 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7757 desc = "LAN: Canceled";
7758 break;
7759
7760/****************************************************************************/
7761/* Serial Attached SCSI values */
7762/****************************************************************************/
7763
7764 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7765 desc = "SAS: SMP Request Failed";
7766 break;
7767
7768 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7769 desc = "SAS: SMP Data Overrun";
7770 break;
7771
7772 default:
7773 desc = "Others";
7774 break;
7775 }
7776
7777 if (!desc)
7778 return;
7779
7780 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7781 ioc->name, status, desc));
7782}
7783
7784/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7785EXPORT_SYMBOL(mpt_attach);
7786EXPORT_SYMBOL(mpt_detach);
7787#ifdef CONFIG_PM
7788EXPORT_SYMBOL(mpt_resume);
7789EXPORT_SYMBOL(mpt_suspend);
7790#endif
7791EXPORT_SYMBOL(ioc_list);
7792EXPORT_SYMBOL(mpt_register);
7793EXPORT_SYMBOL(mpt_deregister);
7794EXPORT_SYMBOL(mpt_event_register);
7795EXPORT_SYMBOL(mpt_event_deregister);
7796EXPORT_SYMBOL(mpt_reset_register);
7797EXPORT_SYMBOL(mpt_reset_deregister);
7798EXPORT_SYMBOL(mpt_device_driver_register);
7799EXPORT_SYMBOL(mpt_device_driver_deregister);
7800EXPORT_SYMBOL(mpt_get_msg_frame);
7801EXPORT_SYMBOL(mpt_put_msg_frame);
7802EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7803EXPORT_SYMBOL(mpt_free_msg_frame);
7804EXPORT_SYMBOL(mpt_send_handshake_request);
7805EXPORT_SYMBOL(mpt_verify_adapter);
7806EXPORT_SYMBOL(mpt_GetIocState);
7807EXPORT_SYMBOL(mpt_print_ioc_summary);
7808EXPORT_SYMBOL(mpt_HardResetHandler);
7809EXPORT_SYMBOL(mpt_config);
7810EXPORT_SYMBOL(mpt_findImVolumes);
7811EXPORT_SYMBOL(mpt_alloc_fw_memory);
7812EXPORT_SYMBOL(mpt_free_fw_memory);
7813EXPORT_SYMBOL(mptbase_sas_persist_operation);
7814EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7815
7816/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7817/**
7818 * fusion_init - Fusion MPT base driver initialization routine.
7819 *
7820 * Returns 0 for success, non-zero for failure.
7821 */
7822static int __init
7823fusion_init(void)
7824{
7825 u8 cb_idx;
7826
7827 show_mptmod_ver(my_NAME, my_VERSION);
7828 printk(KERN_INFO COPYRIGHT "\n");
7829
7830 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7831 MptCallbacks[cb_idx] = NULL;
7832 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7833 MptEvHandlers[cb_idx] = NULL;
7834 MptResetHandlers[cb_idx] = NULL;
7835 }
7836
7837 /* Register ourselves (mptbase) in order to facilitate
7838 * EventNotification handling.
7839 */
7840 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7841
7842 /* Register for hard reset handling callbacks.
7843 */
7844 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7845
7846#ifdef CONFIG_PROC_FS
7847 (void) procmpt_create();
7848#endif
7849 return 0;
7850}
7851
7852/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7853/**
7854 * fusion_exit - Perform driver unload cleanup.
7855 *
7856 * This routine frees all resources associated with each MPT adapter
7857 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7858 */
7859static void __exit
7860fusion_exit(void)
7861{
7862
7863 mpt_reset_deregister(mpt_base_index);
7864
7865#ifdef CONFIG_PROC_FS
7866 procmpt_destroy();
7867#endif
7868}
7869
7870module_init(fusion_init);
7871module_exit(fusion_exit);