Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/message/fusion/mptfc.c
15109 views
1
/*
2
* linux/drivers/message/fusion/mptfc.c
3
* For use with LSI PCI chip/adapter(s)
4
* running LSI Fusion MPT (Message Passing Technology) firmware.
5
*
6
* Copyright (c) 1999-2008 LSI Corporation
7
* (mailto:[email protected])
8
*
9
*/
10
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11
/*
12
This program is free software; you can redistribute it and/or modify
13
it under the terms of the GNU General Public License as published by
14
the Free Software Foundation; version 2 of the License.
15
16
This program is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
GNU General Public License for more details.
20
21
NO WARRANTY
22
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26
solely responsible for determining the appropriateness of using and
27
distributing the Program and assumes all risks associated with its
28
exercise of rights under this Agreement, including but not limited to
29
the risks and costs of program errors, damage to or loss of data,
30
programs or equipment, and unavailability or interruption of operations.
31
32
DISCLAIMER OF LIABILITY
33
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41
You should have received a copy of the GNU General Public License
42
along with this program; if not, write to the Free Software
43
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44
*/
45
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
#include <linux/module.h>
47
#include <linux/kernel.h>
48
#include <linux/init.h>
49
#include <linux/errno.h>
50
#include <linux/kdev_t.h>
51
#include <linux/blkdev.h>
52
#include <linux/delay.h> /* for mdelay */
53
#include <linux/interrupt.h> /* needed for in_interrupt() proto */
54
#include <linux/reboot.h> /* notifier code */
55
#include <linux/workqueue.h>
56
#include <linux/sort.h>
57
#include <linux/slab.h>
58
59
#include <scsi/scsi.h>
60
#include <scsi/scsi_cmnd.h>
61
#include <scsi/scsi_device.h>
62
#include <scsi/scsi_host.h>
63
#include <scsi/scsi_tcq.h>
64
#include <scsi/scsi_transport_fc.h>
65
66
#include "mptbase.h"
67
#include "mptscsih.h"
68
69
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70
#define my_NAME "Fusion MPT FC Host driver"
71
#define my_VERSION MPT_LINUX_VERSION_COMMON
72
#define MYNAM "mptfc"
73
74
MODULE_AUTHOR(MODULEAUTHOR);
75
MODULE_DESCRIPTION(my_NAME);
76
MODULE_LICENSE("GPL");
77
MODULE_VERSION(my_VERSION);
78
79
/* Command line args */
80
#define MPTFC_DEV_LOSS_TMO (60)
81
static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
82
module_param(mptfc_dev_loss_tmo, int, 0);
83
MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
84
" transport to wait for an rport to "
85
" return following a device loss event."
86
" Default=60.");
87
88
/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
89
#define MPTFC_MAX_LUN (16895)
90
static int max_lun = MPTFC_MAX_LUN;
91
module_param(max_lun, int, 0);
92
MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
93
94
static u8 mptfcDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
95
static u8 mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
96
static u8 mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
97
98
static int mptfc_target_alloc(struct scsi_target *starget);
99
static int mptfc_slave_alloc(struct scsi_device *sdev);
100
static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
101
static void mptfc_target_destroy(struct scsi_target *starget);
102
static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
103
static void __devexit mptfc_remove(struct pci_dev *pdev);
104
static int mptfc_abort(struct scsi_cmnd *SCpnt);
105
static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
106
static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
107
static int mptfc_host_reset(struct scsi_cmnd *SCpnt);
108
109
static struct scsi_host_template mptfc_driver_template = {
110
.module = THIS_MODULE,
111
.proc_name = "mptfc",
112
.proc_info = mptscsih_proc_info,
113
.name = "MPT FC Host",
114
.info = mptscsih_info,
115
.queuecommand = mptfc_qcmd,
116
.target_alloc = mptfc_target_alloc,
117
.slave_alloc = mptfc_slave_alloc,
118
.slave_configure = mptscsih_slave_configure,
119
.target_destroy = mptfc_target_destroy,
120
.slave_destroy = mptscsih_slave_destroy,
121
.change_queue_depth = mptscsih_change_queue_depth,
122
.eh_abort_handler = mptfc_abort,
123
.eh_device_reset_handler = mptfc_dev_reset,
124
.eh_bus_reset_handler = mptfc_bus_reset,
125
.eh_host_reset_handler = mptfc_host_reset,
126
.bios_param = mptscsih_bios_param,
127
.can_queue = MPT_FC_CAN_QUEUE,
128
.this_id = -1,
129
.sg_tablesize = MPT_SCSI_SG_DEPTH,
130
.max_sectors = 8192,
131
.cmd_per_lun = 7,
132
.use_clustering = ENABLE_CLUSTERING,
133
.shost_attrs = mptscsih_host_attrs,
134
};
135
136
/****************************************************************************
137
* Supported hardware
138
*/
139
140
static struct pci_device_id mptfc_pci_table[] = {
141
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
142
PCI_ANY_ID, PCI_ANY_ID },
143
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
144
PCI_ANY_ID, PCI_ANY_ID },
145
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
146
PCI_ANY_ID, PCI_ANY_ID },
147
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
148
PCI_ANY_ID, PCI_ANY_ID },
149
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
150
PCI_ANY_ID, PCI_ANY_ID },
151
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
152
PCI_ANY_ID, PCI_ANY_ID },
153
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
154
PCI_ANY_ID, PCI_ANY_ID },
155
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
156
PCI_ANY_ID, PCI_ANY_ID },
157
{ PCI_VENDOR_ID_BROCADE, MPI_MANUFACTPAGE_DEVICEID_FC949E,
158
PCI_ANY_ID, PCI_ANY_ID },
159
{0} /* Terminating entry */
160
};
161
MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
162
163
static struct scsi_transport_template *mptfc_transport_template = NULL;
164
165
static struct fc_function_template mptfc_transport_functions = {
166
.dd_fcrport_size = 8,
167
.show_host_node_name = 1,
168
.show_host_port_name = 1,
169
.show_host_supported_classes = 1,
170
.show_host_port_id = 1,
171
.show_rport_supported_classes = 1,
172
.show_starget_node_name = 1,
173
.show_starget_port_name = 1,
174
.show_starget_port_id = 1,
175
.set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
176
.show_rport_dev_loss_tmo = 1,
177
.show_host_supported_speeds = 1,
178
.show_host_maxframe_size = 1,
179
.show_host_speed = 1,
180
.show_host_fabric_name = 1,
181
.show_host_port_type = 1,
182
.show_host_port_state = 1,
183
.show_host_symbolic_name = 1,
184
};
185
186
static int
187
mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
188
int (*func)(struct scsi_cmnd *SCpnt),
189
const char *caller)
190
{
191
MPT_SCSI_HOST *hd;
192
struct scsi_device *sdev = SCpnt->device;
193
struct Scsi_Host *shost = sdev->host;
194
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
195
unsigned long flags;
196
int ready;
197
MPT_ADAPTER *ioc;
198
int loops = 40; /* seconds */
199
200
hd = shost_priv(SCpnt->device->host);
201
ioc = hd->ioc;
202
spin_lock_irqsave(shost->host_lock, flags);
203
while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
204
|| (loops > 0 && ioc->active == 0)) {
205
spin_unlock_irqrestore(shost->host_lock, flags);
206
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
207
"mptfc_block_error_handler.%d: %d:%d, port status is "
208
"%x, active flag %d, deferring %s recovery.\n",
209
ioc->name, ioc->sh->host_no,
210
SCpnt->device->id, SCpnt->device->lun,
211
ready, ioc->active, caller));
212
msleep(1000);
213
spin_lock_irqsave(shost->host_lock, flags);
214
loops --;
215
}
216
spin_unlock_irqrestore(shost->host_lock, flags);
217
218
if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
219
|| ioc->active == 0) {
220
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
221
"%s.%d: %d:%d, failing recovery, "
222
"port state %x, active %d, vdevice %p.\n", caller,
223
ioc->name, ioc->sh->host_no,
224
SCpnt->device->id, SCpnt->device->lun, ready,
225
ioc->active, SCpnt->device->hostdata));
226
return FAILED;
227
}
228
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
229
"%s.%d: %d:%d, executing recovery.\n", caller,
230
ioc->name, ioc->sh->host_no,
231
SCpnt->device->id, SCpnt->device->lun));
232
return (*func)(SCpnt);
233
}
234
235
static int
236
mptfc_abort(struct scsi_cmnd *SCpnt)
237
{
238
return
239
mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
240
}
241
242
static int
243
mptfc_dev_reset(struct scsi_cmnd *SCpnt)
244
{
245
return
246
mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
247
}
248
249
static int
250
mptfc_bus_reset(struct scsi_cmnd *SCpnt)
251
{
252
return
253
mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
254
}
255
256
static int
257
mptfc_host_reset(struct scsi_cmnd *SCpnt)
258
{
259
return
260
mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __func__);
261
}
262
263
static void
264
mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
265
{
266
if (timeout > 0)
267
rport->dev_loss_tmo = timeout;
268
else
269
rport->dev_loss_tmo = mptfc_dev_loss_tmo;
270
}
271
272
static int
273
mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
274
{
275
FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
276
FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
277
278
if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
279
if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
280
return 0;
281
if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
282
return -1;
283
return 1;
284
}
285
if ((*aa)->CurrentBus < (*bb)->CurrentBus)
286
return -1;
287
return 1;
288
}
289
290
static int
291
mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
292
void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
293
{
294
ConfigPageHeader_t hdr;
295
CONFIGPARMS cfg;
296
FCDevicePage0_t *ppage0_alloc, *fc;
297
dma_addr_t page0_dma;
298
int data_sz;
299
int ii;
300
301
FCDevicePage0_t *p0_array=NULL, *p_p0;
302
FCDevicePage0_t **pp0_array=NULL, **p_pp0;
303
304
int rc = -ENOMEM;
305
U32 port_id = 0xffffff;
306
int num_targ = 0;
307
int max_bus = ioc->facts.MaxBuses;
308
int max_targ;
309
310
max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices;
311
312
data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
313
p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
314
if (!p0_array)
315
goto out;
316
317
data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
318
p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
319
if (!pp0_array)
320
goto out;
321
322
do {
323
/* Get FC Device Page 0 header */
324
hdr.PageVersion = 0;
325
hdr.PageLength = 0;
326
hdr.PageNumber = 0;
327
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
328
cfg.cfghdr.hdr = &hdr;
329
cfg.physAddr = -1;
330
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
331
cfg.dir = 0;
332
cfg.pageAddr = port_id;
333
cfg.timeout = 0;
334
335
if ((rc = mpt_config(ioc, &cfg)) != 0)
336
break;
337
338
if (hdr.PageLength <= 0)
339
break;
340
341
data_sz = hdr.PageLength * 4;
342
ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
343
&page0_dma);
344
rc = -ENOMEM;
345
if (!ppage0_alloc)
346
break;
347
348
cfg.physAddr = page0_dma;
349
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
350
351
if ((rc = mpt_config(ioc, &cfg)) == 0) {
352
ppage0_alloc->PortIdentifier =
353
le32_to_cpu(ppage0_alloc->PortIdentifier);
354
355
ppage0_alloc->WWNN.Low =
356
le32_to_cpu(ppage0_alloc->WWNN.Low);
357
358
ppage0_alloc->WWNN.High =
359
le32_to_cpu(ppage0_alloc->WWNN.High);
360
361
ppage0_alloc->WWPN.Low =
362
le32_to_cpu(ppage0_alloc->WWPN.Low);
363
364
ppage0_alloc->WWPN.High =
365
le32_to_cpu(ppage0_alloc->WWPN.High);
366
367
ppage0_alloc->BBCredit =
368
le16_to_cpu(ppage0_alloc->BBCredit);
369
370
ppage0_alloc->MaxRxFrameSize =
371
le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
372
373
port_id = ppage0_alloc->PortIdentifier;
374
num_targ++;
375
*p_p0 = *ppage0_alloc; /* save data */
376
*p_pp0++ = p_p0++; /* save addr */
377
}
378
pci_free_consistent(ioc->pcidev, data_sz,
379
(u8 *) ppage0_alloc, page0_dma);
380
if (rc != 0)
381
break;
382
383
} while (port_id <= 0xff0000);
384
385
if (num_targ) {
386
/* sort array */
387
if (num_targ > 1)
388
sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
389
mptfc_FcDevPage0_cmp_func, NULL);
390
/* call caller's func for each targ */
391
for (ii = 0; ii < num_targ; ii++) {
392
fc = *(pp0_array+ii);
393
func(ioc, ioc_port, fc);
394
}
395
}
396
397
out:
398
kfree(pp0_array);
399
kfree(p0_array);
400
return rc;
401
}
402
403
static int
404
mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
405
{
406
/* not currently usable */
407
if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
408
MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
409
return -1;
410
411
if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
412
return -1;
413
414
if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
415
return -1;
416
417
/*
418
* board data structure already normalized to platform endianness
419
* shifted to avoid unaligned access on 64 bit architecture
420
*/
421
rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
422
rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
423
rid->port_id = pg0->PortIdentifier;
424
rid->roles = FC_RPORT_ROLE_UNKNOWN;
425
426
return 0;
427
}
428
429
static void
430
mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
431
{
432
struct fc_rport_identifiers rport_ids;
433
struct fc_rport *rport;
434
struct mptfc_rport_info *ri;
435
int new_ri = 1;
436
u64 pn, nn;
437
VirtTarget *vtarget;
438
u32 roles = FC_RPORT_ROLE_UNKNOWN;
439
440
if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
441
return;
442
443
roles |= FC_RPORT_ROLE_FCP_TARGET;
444
if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
445
roles |= FC_RPORT_ROLE_FCP_INITIATOR;
446
447
/* scan list looking for a match */
448
list_for_each_entry(ri, &ioc->fc_rports, list) {
449
pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
450
if (pn == rport_ids.port_name) { /* match */
451
list_move_tail(&ri->list, &ioc->fc_rports);
452
new_ri = 0;
453
break;
454
}
455
}
456
if (new_ri) { /* allocate one */
457
ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
458
if (!ri)
459
return;
460
list_add_tail(&ri->list, &ioc->fc_rports);
461
}
462
463
ri->pg0 = *pg0; /* add/update pg0 data */
464
ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
465
466
/* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
467
if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
468
ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
469
rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
470
if (rport) {
471
ri->rport = rport;
472
if (new_ri) /* may have been reset by user */
473
rport->dev_loss_tmo = mptfc_dev_loss_tmo;
474
/*
475
* if already mapped, remap here. If not mapped,
476
* target_alloc will allocate vtarget and map,
477
* slave_alloc will fill in vdevice from vtarget.
478
*/
479
if (ri->starget) {
480
vtarget = ri->starget->hostdata;
481
if (vtarget) {
482
vtarget->id = pg0->CurrentTargetID;
483
vtarget->channel = pg0->CurrentBus;
484
vtarget->deleted = 0;
485
}
486
}
487
*((struct mptfc_rport_info **)rport->dd_data) = ri;
488
/* scan will be scheduled once rport becomes a target */
489
fc_remote_port_rolechg(rport,roles);
490
491
pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
492
nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
493
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
494
"mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
495
"rport tid %d, tmo %d\n",
496
ioc->name,
497
ioc->sh->host_no,
498
pg0->PortIdentifier,
499
(unsigned long long)nn,
500
(unsigned long long)pn,
501
pg0->CurrentTargetID,
502
ri->rport->scsi_target_id,
503
ri->rport->dev_loss_tmo));
504
} else {
505
list_del(&ri->list);
506
kfree(ri);
507
ri = NULL;
508
}
509
}
510
}
511
512
/*
513
* OS entry point to allow for host driver to free allocated memory
514
* Called if no device present or device being unloaded
515
*/
516
static void
517
mptfc_target_destroy(struct scsi_target *starget)
518
{
519
struct fc_rport *rport;
520
struct mptfc_rport_info *ri;
521
522
rport = starget_to_rport(starget);
523
if (rport) {
524
ri = *((struct mptfc_rport_info **)rport->dd_data);
525
if (ri) /* better be! */
526
ri->starget = NULL;
527
}
528
if (starget->hostdata)
529
kfree(starget->hostdata);
530
starget->hostdata = NULL;
531
}
532
533
/*
534
* OS entry point to allow host driver to alloc memory
535
* for each scsi target. Called once per device the bus scan.
536
* Return non-zero if allocation fails.
537
*/
538
static int
539
mptfc_target_alloc(struct scsi_target *starget)
540
{
541
VirtTarget *vtarget;
542
struct fc_rport *rport;
543
struct mptfc_rport_info *ri;
544
int rc;
545
546
vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
547
if (!vtarget)
548
return -ENOMEM;
549
starget->hostdata = vtarget;
550
551
rc = -ENODEV;
552
rport = starget_to_rport(starget);
553
if (rport) {
554
ri = *((struct mptfc_rport_info **)rport->dd_data);
555
if (ri) { /* better be! */
556
vtarget->id = ri->pg0.CurrentTargetID;
557
vtarget->channel = ri->pg0.CurrentBus;
558
ri->starget = starget;
559
rc = 0;
560
}
561
}
562
if (rc != 0) {
563
kfree(vtarget);
564
starget->hostdata = NULL;
565
}
566
567
return rc;
568
}
569
/*
570
* mptfc_dump_lun_info
571
* @ioc
572
* @rport
573
* @sdev
574
*
575
*/
576
static void
577
mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device *sdev,
578
VirtTarget *vtarget)
579
{
580
u64 nn, pn;
581
struct mptfc_rport_info *ri;
582
583
ri = *((struct mptfc_rport_info **)rport->dd_data);
584
pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
585
nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
586
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
587
"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
588
"CurrentTargetID %d, %x %llx %llx\n",
589
ioc->name,
590
sdev->host->host_no,
591
vtarget->num_luns,
592
sdev->id, ri->pg0.CurrentTargetID,
593
ri->pg0.PortIdentifier,
594
(unsigned long long)pn,
595
(unsigned long long)nn));
596
}
597
598
599
/*
600
* OS entry point to allow host driver to alloc memory
601
* for each scsi device. Called once per device the bus scan.
602
* Return non-zero if allocation fails.
603
* Init memory once per LUN.
604
*/
605
static int
606
mptfc_slave_alloc(struct scsi_device *sdev)
607
{
608
MPT_SCSI_HOST *hd;
609
VirtTarget *vtarget;
610
VirtDevice *vdevice;
611
struct scsi_target *starget;
612
struct fc_rport *rport;
613
MPT_ADAPTER *ioc;
614
615
starget = scsi_target(sdev);
616
rport = starget_to_rport(starget);
617
618
if (!rport || fc_remote_port_chkready(rport))
619
return -ENXIO;
620
621
hd = shost_priv(sdev->host);
622
ioc = hd->ioc;
623
624
vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
625
if (!vdevice) {
626
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
627
ioc->name, sizeof(VirtDevice));
628
return -ENOMEM;
629
}
630
631
632
sdev->hostdata = vdevice;
633
vtarget = starget->hostdata;
634
635
if (vtarget->num_luns == 0) {
636
vtarget->ioc_id = ioc->id;
637
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
638
}
639
640
vdevice->vtarget = vtarget;
641
vdevice->lun = sdev->lun;
642
643
vtarget->num_luns++;
644
645
646
mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
647
648
return 0;
649
}
650
651
static int
652
mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
653
{
654
struct mptfc_rport_info *ri;
655
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
656
int err;
657
VirtDevice *vdevice = SCpnt->device->hostdata;
658
659
if (!vdevice || !vdevice->vtarget) {
660
SCpnt->result = DID_NO_CONNECT << 16;
661
done(SCpnt);
662
return 0;
663
}
664
665
err = fc_remote_port_chkready(rport);
666
if (unlikely(err)) {
667
SCpnt->result = err;
668
done(SCpnt);
669
return 0;
670
}
671
672
/* dd_data is null until finished adding target */
673
ri = *((struct mptfc_rport_info **)rport->dd_data);
674
if (unlikely(!ri)) {
675
SCpnt->result = DID_IMM_RETRY << 16;
676
done(SCpnt);
677
return 0;
678
}
679
680
return mptscsih_qcmd(SCpnt,done);
681
}
682
683
static DEF_SCSI_QCMD(mptfc_qcmd)
684
685
/*
686
* mptfc_display_port_link_speed - displaying link speed
687
* @ioc: Pointer to MPT_ADAPTER structure
688
* @portnum: IOC Port number
689
* @pp0dest: port page0 data payload
690
*
691
*/
692
static void
693
mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
694
{
695
u8 old_speed, new_speed, state;
696
char *old, *new;
697
698
if (portnum >= 2)
699
return;
700
701
old_speed = ioc->fc_link_speed[portnum];
702
new_speed = pp0dest->CurrentSpeed;
703
state = pp0dest->PortState;
704
705
if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
706
new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN) {
707
708
old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
709
old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
710
old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
711
"Unknown";
712
new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
713
new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
714
new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
715
"Unknown";
716
if (old_speed == 0)
717
printk(MYIOC_s_NOTE_FMT
718
"FC Link Established, Speed = %s\n",
719
ioc->name, new);
720
else if (old_speed != new_speed)
721
printk(MYIOC_s_WARN_FMT
722
"FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
723
ioc->name, old, new);
724
725
ioc->fc_link_speed[portnum] = new_speed;
726
}
727
}
728
729
/*
730
* mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
731
* @ioc: Pointer to MPT_ADAPTER structure
732
* @portnum: IOC Port number
733
*
734
* Return: 0 for success
735
* -ENOMEM if no memory available
736
* -EPERM if not allowed due to ISR context
737
* -EAGAIN if no msg frames currently available
738
* -EFAULT for non-successful reply or no reply (timeout)
739
* -EINVAL portnum arg out of range (hardwired to two elements)
740
*/
741
static int
742
mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
743
{
744
ConfigPageHeader_t hdr;
745
CONFIGPARMS cfg;
746
FCPortPage0_t *ppage0_alloc;
747
FCPortPage0_t *pp0dest;
748
dma_addr_t page0_dma;
749
int data_sz;
750
int copy_sz;
751
int rc;
752
int count = 400;
753
754
if (portnum > 1)
755
return -EINVAL;
756
757
/* Get FCPort Page 0 header */
758
hdr.PageVersion = 0;
759
hdr.PageLength = 0;
760
hdr.PageNumber = 0;
761
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
762
cfg.cfghdr.hdr = &hdr;
763
cfg.physAddr = -1;
764
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
765
cfg.dir = 0;
766
cfg.pageAddr = portnum;
767
cfg.timeout = 0;
768
769
if ((rc = mpt_config(ioc, &cfg)) != 0)
770
return rc;
771
772
if (hdr.PageLength == 0)
773
return 0;
774
775
data_sz = hdr.PageLength * 4;
776
rc = -ENOMEM;
777
ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
778
if (ppage0_alloc) {
779
780
try_again:
781
memset((u8 *)ppage0_alloc, 0, data_sz);
782
cfg.physAddr = page0_dma;
783
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
784
785
if ((rc = mpt_config(ioc, &cfg)) == 0) {
786
/* save the data */
787
pp0dest = &ioc->fc_port_page0[portnum];
788
copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
789
memcpy(pp0dest, ppage0_alloc, copy_sz);
790
791
/*
792
* Normalize endianness of structure data,
793
* by byte-swapping all > 1 byte fields!
794
*/
795
pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
796
pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
797
pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
798
pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
799
pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
800
pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
801
pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
802
pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
803
pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
804
pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
805
pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
806
pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
807
pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
808
pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
809
pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
810
pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
811
812
/*
813
* if still doing discovery,
814
* hang loose a while until finished
815
*/
816
if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
817
(pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
818
(pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
819
== MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
820
if (count-- > 0) {
821
msleep(100);
822
goto try_again;
823
}
824
printk(MYIOC_s_INFO_FMT "Firmware discovery not"
825
" complete.\n",
826
ioc->name);
827
}
828
mptfc_display_port_link_speed(ioc, portnum, pp0dest);
829
}
830
831
pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
832
}
833
834
return rc;
835
}
836
837
static int
838
mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
839
{
840
ConfigPageHeader_t hdr;
841
CONFIGPARMS cfg;
842
int rc;
843
844
if (portnum > 1)
845
return -EINVAL;
846
847
if (!(ioc->fc_data.fc_port_page1[portnum].data))
848
return -EINVAL;
849
850
/* get fcport page 1 header */
851
hdr.PageVersion = 0;
852
hdr.PageLength = 0;
853
hdr.PageNumber = 1;
854
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
855
cfg.cfghdr.hdr = &hdr;
856
cfg.physAddr = -1;
857
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
858
cfg.dir = 0;
859
cfg.pageAddr = portnum;
860
cfg.timeout = 0;
861
862
if ((rc = mpt_config(ioc, &cfg)) != 0)
863
return rc;
864
865
if (hdr.PageLength == 0)
866
return -ENODEV;
867
868
if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
869
return -EINVAL;
870
871
cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
872
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
873
cfg.dir = 1;
874
875
rc = mpt_config(ioc, &cfg);
876
877
return rc;
878
}
879
880
static int
881
mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
882
{
883
ConfigPageHeader_t hdr;
884
CONFIGPARMS cfg;
885
FCPortPage1_t *page1_alloc;
886
dma_addr_t page1_dma;
887
int data_sz;
888
int rc;
889
890
if (portnum > 1)
891
return -EINVAL;
892
893
/* get fcport page 1 header */
894
hdr.PageVersion = 0;
895
hdr.PageLength = 0;
896
hdr.PageNumber = 1;
897
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
898
cfg.cfghdr.hdr = &hdr;
899
cfg.physAddr = -1;
900
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
901
cfg.dir = 0;
902
cfg.pageAddr = portnum;
903
cfg.timeout = 0;
904
905
if ((rc = mpt_config(ioc, &cfg)) != 0)
906
return rc;
907
908
if (hdr.PageLength == 0)
909
return -ENODEV;
910
911
start_over:
912
913
if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
914
data_sz = hdr.PageLength * 4;
915
if (data_sz < sizeof(FCPortPage1_t))
916
data_sz = sizeof(FCPortPage1_t);
917
918
page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
919
data_sz,
920
&page1_dma);
921
if (!page1_alloc)
922
return -ENOMEM;
923
}
924
else {
925
page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
926
page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
927
data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
928
if (hdr.PageLength * 4 > data_sz) {
929
ioc->fc_data.fc_port_page1[portnum].data = NULL;
930
pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
931
page1_alloc, page1_dma);
932
goto start_over;
933
}
934
}
935
936
memset(page1_alloc,0,data_sz);
937
938
cfg.physAddr = page1_dma;
939
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
940
941
if ((rc = mpt_config(ioc, &cfg)) == 0) {
942
ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
943
ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
944
ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
945
}
946
else {
947
ioc->fc_data.fc_port_page1[portnum].data = NULL;
948
pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
949
page1_alloc, page1_dma);
950
}
951
952
return rc;
953
}
954
955
static void
956
mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
957
{
958
int ii;
959
FCPortPage1_t *pp1;
960
961
#define MPTFC_FW_DEVICE_TIMEOUT (1)
962
#define MPTFC_FW_IO_PEND_TIMEOUT (1)
963
#define ON_FLAGS (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
964
#define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
965
966
for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
967
if (mptfc_GetFcPortPage1(ioc, ii) != 0)
968
continue;
969
pp1 = ioc->fc_data.fc_port_page1[ii].data;
970
if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
971
&& (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
972
&& ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
973
&& ((pp1->Flags & OFF_FLAGS) == 0))
974
continue;
975
pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
976
pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
977
pp1->Flags &= ~OFF_FLAGS;
978
pp1->Flags |= ON_FLAGS;
979
mptfc_WriteFcPortPage1(ioc, ii);
980
}
981
}
982
983
984
static void
985
mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
986
{
987
unsigned class = 0;
988
unsigned cos = 0;
989
unsigned speed;
990
unsigned port_type;
991
unsigned port_state;
992
FCPortPage0_t *pp0;
993
struct Scsi_Host *sh;
994
char *sn;
995
996
/* don't know what to do as only one scsi (fc) host was allocated */
997
if (portnum != 0)
998
return;
999
1000
pp0 = &ioc->fc_port_page0[portnum];
1001
sh = ioc->sh;
1002
1003
sn = fc_host_symbolic_name(sh);
1004
snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
1005
ioc->prod_name,
1006
MPT_FW_REV_MAGIC_ID_STRING,
1007
ioc->facts.FWVersion.Word);
1008
1009
fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
1010
1011
fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
1012
1013
fc_host_node_name(sh) =
1014
(u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1015
1016
fc_host_port_name(sh) =
1017
(u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
1018
1019
fc_host_port_id(sh) = pp0->PortIdentifier;
1020
1021
class = pp0->SupportedServiceClass;
1022
if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
1023
cos |= FC_COS_CLASS1;
1024
if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
1025
cos |= FC_COS_CLASS2;
1026
if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
1027
cos |= FC_COS_CLASS3;
1028
fc_host_supported_classes(sh) = cos;
1029
1030
if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
1031
speed = FC_PORTSPEED_1GBIT;
1032
else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
1033
speed = FC_PORTSPEED_2GBIT;
1034
else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
1035
speed = FC_PORTSPEED_4GBIT;
1036
else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
1037
speed = FC_PORTSPEED_10GBIT;
1038
else
1039
speed = FC_PORTSPEED_UNKNOWN;
1040
fc_host_speed(sh) = speed;
1041
1042
speed = 0;
1043
if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
1044
speed |= FC_PORTSPEED_1GBIT;
1045
if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
1046
speed |= FC_PORTSPEED_2GBIT;
1047
if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
1048
speed |= FC_PORTSPEED_4GBIT;
1049
if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
1050
speed |= FC_PORTSPEED_10GBIT;
1051
fc_host_supported_speeds(sh) = speed;
1052
1053
port_state = FC_PORTSTATE_UNKNOWN;
1054
if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
1055
port_state = FC_PORTSTATE_ONLINE;
1056
else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
1057
port_state = FC_PORTSTATE_LINKDOWN;
1058
fc_host_port_state(sh) = port_state;
1059
1060
port_type = FC_PORTTYPE_UNKNOWN;
1061
if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
1062
port_type = FC_PORTTYPE_PTP;
1063
else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
1064
port_type = FC_PORTTYPE_LPORT;
1065
else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
1066
port_type = FC_PORTTYPE_NLPORT;
1067
else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
1068
port_type = FC_PORTTYPE_NPORT;
1069
fc_host_port_type(sh) = port_type;
1070
1071
fc_host_fabric_name(sh) =
1072
(pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
1073
(u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
1074
(u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1075
1076
}
1077
1078
static void
1079
mptfc_link_status_change(struct work_struct *work)
1080
{
1081
MPT_ADAPTER *ioc =
1082
container_of(work, MPT_ADAPTER, fc_rescan_work);
1083
int ii;
1084
1085
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
1086
(void) mptfc_GetFcPortPage0(ioc, ii);
1087
1088
}
1089
1090
static void
1091
mptfc_setup_reset(struct work_struct *work)
1092
{
1093
MPT_ADAPTER *ioc =
1094
container_of(work, MPT_ADAPTER, fc_setup_reset_work);
1095
u64 pn;
1096
struct mptfc_rport_info *ri;
1097
struct scsi_target *starget;
1098
VirtTarget *vtarget;
1099
1100
/* reset about to happen, delete (block) all rports */
1101
list_for_each_entry(ri, &ioc->fc_rports, list) {
1102
if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1103
ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
1104
fc_remote_port_delete(ri->rport); /* won't sleep */
1105
ri->rport = NULL;
1106
starget = ri->starget;
1107
if (starget) {
1108
vtarget = starget->hostdata;
1109
if (vtarget)
1110
vtarget->deleted = 1;
1111
}
1112
1113
pn = (u64)ri->pg0.WWPN.High << 32 |
1114
(u64)ri->pg0.WWPN.Low;
1115
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1116
"mptfc_setup_reset.%d: %llx deleted\n",
1117
ioc->name,
1118
ioc->sh->host_no,
1119
(unsigned long long)pn));
1120
}
1121
}
1122
}
1123
1124
static void
1125
mptfc_rescan_devices(struct work_struct *work)
1126
{
1127
MPT_ADAPTER *ioc =
1128
container_of(work, MPT_ADAPTER, fc_rescan_work);
1129
int ii;
1130
u64 pn;
1131
struct mptfc_rport_info *ri;
1132
struct scsi_target *starget;
1133
VirtTarget *vtarget;
1134
1135
/* start by tagging all ports as missing */
1136
list_for_each_entry(ri, &ioc->fc_rports, list) {
1137
if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1138
ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
1139
}
1140
}
1141
1142
/*
1143
* now rescan devices known to adapter,
1144
* will reregister existing rports
1145
*/
1146
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1147
(void) mptfc_GetFcPortPage0(ioc, ii);
1148
mptfc_init_host_attr(ioc, ii); /* refresh */
1149
mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
1150
}
1151
1152
/* delete devices still missing */
1153
list_for_each_entry(ri, &ioc->fc_rports, list) {
1154
/* if newly missing, delete it */
1155
if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
1156
1157
ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
1158
MPT_RPORT_INFO_FLAGS_MISSING);
1159
fc_remote_port_delete(ri->rport); /* won't sleep */
1160
ri->rport = NULL;
1161
starget = ri->starget;
1162
if (starget) {
1163
vtarget = starget->hostdata;
1164
if (vtarget)
1165
vtarget->deleted = 1;
1166
}
1167
1168
pn = (u64)ri->pg0.WWPN.High << 32 |
1169
(u64)ri->pg0.WWPN.Low;
1170
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1171
"mptfc_rescan.%d: %llx deleted\n",
1172
ioc->name,
1173
ioc->sh->host_no,
1174
(unsigned long long)pn));
1175
}
1176
}
1177
}
1178
1179
static int
1180
mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1181
{
1182
struct Scsi_Host *sh;
1183
MPT_SCSI_HOST *hd;
1184
MPT_ADAPTER *ioc;
1185
unsigned long flags;
1186
int ii;
1187
int numSGE = 0;
1188
int scale;
1189
int ioc_cap;
1190
int error=0;
1191
int r;
1192
1193
if ((r = mpt_attach(pdev,id)) != 0)
1194
return r;
1195
1196
ioc = pci_get_drvdata(pdev);
1197
ioc->DoneCtx = mptfcDoneCtx;
1198
ioc->TaskCtx = mptfcTaskCtx;
1199
ioc->InternalCtx = mptfcInternalCtx;
1200
1201
/* Added sanity check on readiness of the MPT adapter.
1202
*/
1203
if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1204
printk(MYIOC_s_WARN_FMT
1205
"Skipping because it's not operational!\n",
1206
ioc->name);
1207
error = -ENODEV;
1208
goto out_mptfc_probe;
1209
}
1210
1211
if (!ioc->active) {
1212
printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1213
ioc->name);
1214
error = -ENODEV;
1215
goto out_mptfc_probe;
1216
}
1217
1218
/* Sanity check - ensure at least 1 port is INITIATOR capable
1219
*/
1220
ioc_cap = 0;
1221
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1222
if (ioc->pfacts[ii].ProtocolFlags &
1223
MPI_PORTFACTS_PROTOCOL_INITIATOR)
1224
ioc_cap ++;
1225
}
1226
1227
if (!ioc_cap) {
1228
printk(MYIOC_s_WARN_FMT
1229
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1230
ioc->name, ioc);
1231
return 0;
1232
}
1233
1234
sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1235
1236
if (!sh) {
1237
printk(MYIOC_s_WARN_FMT
1238
"Unable to register controller with SCSI subsystem\n",
1239
ioc->name);
1240
error = -1;
1241
goto out_mptfc_probe;
1242
}
1243
1244
spin_lock_init(&ioc->fc_rescan_work_lock);
1245
INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
1246
INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
1247
INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
1248
1249
spin_lock_irqsave(&ioc->FreeQlock, flags);
1250
1251
/* Attach the SCSI Host to the IOC structure
1252
*/
1253
ioc->sh = sh;
1254
1255
sh->io_port = 0;
1256
sh->n_io_port = 0;
1257
sh->irq = 0;
1258
1259
/* set 16 byte cdb's */
1260
sh->max_cmd_len = 16;
1261
1262
sh->max_id = ioc->pfacts->MaxDevices;
1263
sh->max_lun = max_lun;
1264
1265
/* Required entry.
1266
*/
1267
sh->unique_id = ioc->id;
1268
1269
/* Verify that we won't exceed the maximum
1270
* number of chain buffers
1271
* We can optimize: ZZ = req_sz/sizeof(SGE)
1272
* For 32bit SGE's:
1273
* numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1274
* + (req_sz - 64)/sizeof(SGE)
1275
* A slightly different algorithm is required for
1276
* 64bit SGEs.
1277
*/
1278
scale = ioc->req_sz/ioc->SGE_size;
1279
if (ioc->sg_addr_size == sizeof(u64)) {
1280
numSGE = (scale - 1) *
1281
(ioc->facts.MaxChainDepth-1) + scale +
1282
(ioc->req_sz - 60) / ioc->SGE_size;
1283
} else {
1284
numSGE = 1 + (scale - 1) *
1285
(ioc->facts.MaxChainDepth-1) + scale +
1286
(ioc->req_sz - 64) / ioc->SGE_size;
1287
}
1288
1289
if (numSGE < sh->sg_tablesize) {
1290
/* Reset this value */
1291
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1292
"Resetting sg_tablesize to %d from %d\n",
1293
ioc->name, numSGE, sh->sg_tablesize));
1294
sh->sg_tablesize = numSGE;
1295
}
1296
1297
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1298
1299
hd = shost_priv(sh);
1300
hd->ioc = ioc;
1301
1302
/* SCSI needs scsi_cmnd lookup table!
1303
* (with size equal to req_depth*PtrSz!)
1304
*/
1305
ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1306
if (!ioc->ScsiLookup) {
1307
error = -ENOMEM;
1308
goto out_mptfc_probe;
1309
}
1310
spin_lock_init(&ioc->scsi_lookup_lock);
1311
1312
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
1313
ioc->name, ioc->ScsiLookup));
1314
1315
hd->last_queue_full = 0;
1316
1317
sh->transportt = mptfc_transport_template;
1318
error = scsi_add_host (sh, &ioc->pcidev->dev);
1319
if(error) {
1320
dprintk(ioc, printk(MYIOC_s_ERR_FMT
1321
"scsi_add_host failed\n", ioc->name));
1322
goto out_mptfc_probe;
1323
}
1324
1325
/* initialize workqueue */
1326
1327
snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
1328
"mptfc_wq_%d", sh->host_no);
1329
ioc->fc_rescan_work_q =
1330
create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
1331
if (!ioc->fc_rescan_work_q)
1332
goto out_mptfc_probe;
1333
1334
/*
1335
* Pre-fetch FC port WWN and stuff...
1336
* (FCPortPage0_t stuff)
1337
*/
1338
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1339
(void) mptfc_GetFcPortPage0(ioc, ii);
1340
}
1341
mptfc_SetFcPortPage1_defaults(ioc);
1342
1343
/*
1344
* scan for rports -
1345
* by doing it via the workqueue, some locking is eliminated
1346
*/
1347
1348
queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1349
flush_workqueue(ioc->fc_rescan_work_q);
1350
1351
return 0;
1352
1353
out_mptfc_probe:
1354
1355
mptscsih_remove(pdev);
1356
return error;
1357
}
1358
1359
static struct pci_driver mptfc_driver = {
1360
.name = "mptfc",
1361
.id_table = mptfc_pci_table,
1362
.probe = mptfc_probe,
1363
.remove = __devexit_p(mptfc_remove),
1364
.shutdown = mptscsih_shutdown,
1365
#ifdef CONFIG_PM
1366
.suspend = mptscsih_suspend,
1367
.resume = mptscsih_resume,
1368
#endif
1369
};
1370
1371
static int
1372
mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1373
{
1374
MPT_SCSI_HOST *hd;
1375
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1376
unsigned long flags;
1377
int rc=1;
1378
1379
if (ioc->bus_type != FC)
1380
return 0;
1381
1382
devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1383
ioc->name, event));
1384
1385
if (ioc->sh == NULL ||
1386
((hd = shost_priv(ioc->sh)) == NULL))
1387
return 1;
1388
1389
switch (event) {
1390
case MPI_EVENT_RESCAN:
1391
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1392
if (ioc->fc_rescan_work_q) {
1393
queue_work(ioc->fc_rescan_work_q,
1394
&ioc->fc_rescan_work);
1395
}
1396
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1397
break;
1398
case MPI_EVENT_LINK_STATUS_CHANGE:
1399
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1400
if (ioc->fc_rescan_work_q) {
1401
queue_work(ioc->fc_rescan_work_q,
1402
&ioc->fc_lsc_work);
1403
}
1404
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1405
break;
1406
default:
1407
rc = mptscsih_event_process(ioc,pEvReply);
1408
break;
1409
}
1410
return rc;
1411
}
1412
1413
static int
1414
mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1415
{
1416
int rc;
1417
unsigned long flags;
1418
1419
rc = mptscsih_ioc_reset(ioc,reset_phase);
1420
if ((ioc->bus_type != FC) || (!rc))
1421
return rc;
1422
1423
1424
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1425
": IOC %s_reset routed to FC host driver!\n",ioc->name,
1426
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1427
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1428
1429
if (reset_phase == MPT_IOC_SETUP_RESET) {
1430
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1431
if (ioc->fc_rescan_work_q) {
1432
queue_work(ioc->fc_rescan_work_q,
1433
&ioc->fc_setup_reset_work);
1434
}
1435
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1436
}
1437
1438
else if (reset_phase == MPT_IOC_PRE_RESET) {
1439
}
1440
1441
else { /* MPT_IOC_POST_RESET */
1442
mptfc_SetFcPortPage1_defaults(ioc);
1443
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1444
if (ioc->fc_rescan_work_q) {
1445
queue_work(ioc->fc_rescan_work_q,
1446
&ioc->fc_rescan_work);
1447
}
1448
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1449
}
1450
return 1;
1451
}
1452
1453
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1454
/**
1455
* mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
1456
*
1457
* Returns 0 for success, non-zero for failure.
1458
*/
1459
static int __init
1460
mptfc_init(void)
1461
{
1462
int error;
1463
1464
show_mptmod_ver(my_NAME, my_VERSION);
1465
1466
/* sanity check module parameters */
1467
if (mptfc_dev_loss_tmo <= 0)
1468
mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1469
1470
mptfc_transport_template =
1471
fc_attach_transport(&mptfc_transport_functions);
1472
1473
if (!mptfc_transport_template)
1474
return -ENODEV;
1475
1476
mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
1477
"mptscsih_scandv_complete");
1478
mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
1479
"mptscsih_scandv_complete");
1480
mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
1481
"mptscsih_scandv_complete");
1482
1483
mpt_event_register(mptfcDoneCtx, mptfc_event_process);
1484
mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
1485
1486
error = pci_register_driver(&mptfc_driver);
1487
if (error)
1488
fc_release_transport(mptfc_transport_template);
1489
1490
return error;
1491
}
1492
1493
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1494
/**
1495
* mptfc_remove - Remove fc infrastructure for devices
1496
* @pdev: Pointer to pci_dev structure
1497
*
1498
*/
1499
static void __devexit
1500
mptfc_remove(struct pci_dev *pdev)
1501
{
1502
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1503
struct mptfc_rport_info *p, *n;
1504
struct workqueue_struct *work_q;
1505
unsigned long flags;
1506
int ii;
1507
1508
/* destroy workqueue */
1509
if ((work_q=ioc->fc_rescan_work_q)) {
1510
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1511
ioc->fc_rescan_work_q = NULL;
1512
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1513
destroy_workqueue(work_q);
1514
}
1515
1516
fc_remove_host(ioc->sh);
1517
1518
list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1519
list_del(&p->list);
1520
kfree(p);
1521
}
1522
1523
for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1524
if (ioc->fc_data.fc_port_page1[ii].data) {
1525
pci_free_consistent(ioc->pcidev,
1526
ioc->fc_data.fc_port_page1[ii].pg_sz,
1527
(u8 *) ioc->fc_data.fc_port_page1[ii].data,
1528
ioc->fc_data.fc_port_page1[ii].dma);
1529
ioc->fc_data.fc_port_page1[ii].data = NULL;
1530
}
1531
}
1532
1533
mptscsih_remove(pdev);
1534
}
1535
1536
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1537
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1538
/**
1539
* mptfc_exit - Unregisters MPT adapter(s)
1540
*
1541
*/
1542
static void __exit
1543
mptfc_exit(void)
1544
{
1545
pci_unregister_driver(&mptfc_driver);
1546
fc_release_transport(mptfc_transport_template);
1547
1548
mpt_reset_deregister(mptfcDoneCtx);
1549
mpt_event_deregister(mptfcDoneCtx);
1550
1551
mpt_deregister(mptfcInternalCtx);
1552
mpt_deregister(mptfcTaskCtx);
1553
mpt_deregister(mptfcDoneCtx);
1554
}
1555
1556
module_init(mptfc_init);
1557
module_exit(mptfc_exit);
1558
1559