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