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