[SCSI] lpfc: Add range checking for attributes passed as options at load time.
[safe/jmp/linux-2.6] / drivers / scsi / lpfc / lpfc_attr.c
1 /*******************************************************************
2  * This file is part of the Emulex Linux Device Driver for         *
3  * Fibre Channel Host Bus Adapters.                                *
4  * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
5  * EMULEX and SLI are trademarks of Emulex.                        *
6  * www.emulex.com                                                  *
7  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
8  *                                                                 *
9  * This program is free software; you can redistribute it and/or   *
10  * modify it under the terms of version 2 of the GNU General       *
11  * Public License as published by the Free Software Foundation.    *
12  * This program is distributed in the hope that it will be useful. *
13  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
14  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
15  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
16  * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
17  * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
18  * more details, a copy of which can be found in the file COPYING  *
19  * included with this package.                                     *
20  *******************************************************************/
21
22 #include <linux/ctype.h>
23 #include <linux/pci.h>
24 #include <linux/interrupt.h>
25
26 #include <scsi/scsi.h>
27 #include <scsi/scsi_device.h>
28 #include <scsi/scsi_host.h>
29 #include <scsi/scsi_tcq.h>
30 #include <scsi/scsi_transport_fc.h>
31
32 #include "lpfc_hw.h"
33 #include "lpfc_sli.h"
34 #include "lpfc_disc.h"
35 #include "lpfc_scsi.h"
36 #include "lpfc.h"
37 #include "lpfc_logmsg.h"
38 #include "lpfc_version.h"
39 #include "lpfc_compat.h"
40 #include "lpfc_crtn.h"
41
42
43 static void
44 lpfc_jedec_to_ascii(int incr, char hdw[])
45 {
46         int i, j;
47         for (i = 0; i < 8; i++) {
48                 j = (incr & 0xf);
49                 if (j <= 9)
50                         hdw[7 - i] = 0x30 +  j;
51                  else
52                         hdw[7 - i] = 0x61 + j - 10;
53                 incr = (incr >> 4);
54         }
55         hdw[8] = 0;
56         return;
57 }
58
59 static ssize_t
60 lpfc_drvr_version_show(struct class_device *cdev, char *buf)
61 {
62         return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
63 }
64
65 static ssize_t
66 management_version_show(struct class_device *cdev, char *buf)
67 {
68         return snprintf(buf, PAGE_SIZE, DFC_API_VERSION "\n");
69 }
70
71 static ssize_t
72 lpfc_info_show(struct class_device *cdev, char *buf)
73 {
74         struct Scsi_Host *host = class_to_shost(cdev);
75         return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host));
76 }
77
78 static ssize_t
79 lpfc_serialnum_show(struct class_device *cdev, char *buf)
80 {
81         struct Scsi_Host *host = class_to_shost(cdev);
82         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
83         return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber);
84 }
85
86 static ssize_t
87 lpfc_modeldesc_show(struct class_device *cdev, char *buf)
88 {
89         struct Scsi_Host *host = class_to_shost(cdev);
90         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
91         return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc);
92 }
93
94 static ssize_t
95 lpfc_modelname_show(struct class_device *cdev, char *buf)
96 {
97         struct Scsi_Host *host = class_to_shost(cdev);
98         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
99         return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName);
100 }
101
102 static ssize_t
103 lpfc_programtype_show(struct class_device *cdev, char *buf)
104 {
105         struct Scsi_Host *host = class_to_shost(cdev);
106         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
107         return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType);
108 }
109
110 static ssize_t
111 lpfc_portnum_show(struct class_device *cdev, char *buf)
112 {
113         struct Scsi_Host *host = class_to_shost(cdev);
114         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
115         return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port);
116 }
117
118 static ssize_t
119 lpfc_fwrev_show(struct class_device *cdev, char *buf)
120 {
121         struct Scsi_Host *host = class_to_shost(cdev);
122         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
123         char fwrev[32];
124         lpfc_decode_firmware_rev(phba, fwrev, 1);
125         return snprintf(buf, PAGE_SIZE, "%s\n",fwrev);
126 }
127
128 static ssize_t
129 lpfc_hdw_show(struct class_device *cdev, char *buf)
130 {
131         char hdw[9];
132         struct Scsi_Host *host = class_to_shost(cdev);
133         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
134         lpfc_vpd_t *vp = &phba->vpd;
135         lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
136         return snprintf(buf, PAGE_SIZE, "%s\n", hdw);
137 }
138 static ssize_t
139 lpfc_option_rom_version_show(struct class_device *cdev, char *buf)
140 {
141         struct Scsi_Host *host = class_to_shost(cdev);
142         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
143         return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion);
144 }
145 static ssize_t
146 lpfc_state_show(struct class_device *cdev, char *buf)
147 {
148         struct Scsi_Host *host = class_to_shost(cdev);
149         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
150         int len = 0;
151         switch (phba->hba_state) {
152         case LPFC_INIT_START:
153         case LPFC_INIT_MBX_CMDS:
154         case LPFC_LINK_DOWN:
155                 len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n");
156                 break;
157         case LPFC_LINK_UP:
158         case LPFC_LOCAL_CFG_LINK:
159                 len += snprintf(buf + len, PAGE_SIZE-len, "Link Up\n");
160                 break;
161         case LPFC_FLOGI:
162         case LPFC_FABRIC_CFG_LINK:
163         case LPFC_NS_REG:
164         case LPFC_NS_QRY:
165         case LPFC_BUILD_DISC_LIST:
166         case LPFC_DISC_AUTH:
167         case LPFC_CLEAR_LA:
168                 len += snprintf(buf + len, PAGE_SIZE-len,
169                                 "Link Up - Discovery\n");
170                 break;
171         case LPFC_HBA_READY:
172                 len += snprintf(buf + len, PAGE_SIZE-len,
173                                 "Link Up - Ready:\n");
174                 if (phba->fc_topology == TOPOLOGY_LOOP) {
175                         if (phba->fc_flag & FC_PUBLIC_LOOP)
176                                 len += snprintf(buf + len, PAGE_SIZE-len,
177                                                 "   Public Loop\n");
178                         else
179                                 len += snprintf(buf + len, PAGE_SIZE-len,
180                                                 "   Private Loop\n");
181                 } else {
182                         if (phba->fc_flag & FC_FABRIC)
183                                 len += snprintf(buf + len, PAGE_SIZE-len,
184                                                 "   Fabric\n");
185                         else
186                                 len += snprintf(buf + len, PAGE_SIZE-len,
187                                                 "   Point-2-Point\n");
188                 }
189         }
190         return len;
191 }
192
193 static ssize_t
194 lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
195 {
196         struct Scsi_Host *host = class_to_shost(cdev);
197         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
198         return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt +
199                                                         phba->fc_unmap_cnt);
200 }
201
202
203 static int
204 lpfc_issue_lip(struct Scsi_Host *host)
205 {
206         struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
207         LPFC_MBOXQ_t *pmboxq;
208         int mbxstatus = MBXERR_ERROR;
209
210         if ((phba->fc_flag & FC_OFFLINE_MODE) ||
211             (phba->hba_state != LPFC_HBA_READY))
212                 return -EPERM;
213
214         pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
215
216         if (!pmboxq)
217                 return -ENOMEM;
218
219         memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
220         lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed);
221         mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
222
223         if (mbxstatus == MBX_TIMEOUT)
224                 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
225         else
226                 mempool_free(pmboxq, phba->mbox_mem_pool);
227
228         if (mbxstatus == MBXERR_ERROR)
229                 return -EIO;
230
231         return 0;
232 }
233
234 static ssize_t
235 lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
236 {
237         struct Scsi_Host *host = class_to_shost(cdev);
238         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
239         return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
240 }
241
242 static ssize_t
243 lpfc_board_online_show(struct class_device *cdev, char *buf)
244 {
245         struct Scsi_Host *host = class_to_shost(cdev);
246         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
247
248         if (phba->fc_flag & FC_OFFLINE_MODE)
249                 return snprintf(buf, PAGE_SIZE, "0\n");
250         else
251                 return snprintf(buf, PAGE_SIZE, "1\n");
252 }
253
254 static ssize_t
255 lpfc_board_online_store(struct class_device *cdev, const char *buf,
256                                                                 size_t count)
257 {
258         struct Scsi_Host *host = class_to_shost(cdev);
259         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
260         struct completion online_compl;
261         int val=0, status=0;
262
263         if (sscanf(buf, "%d", &val) != 1)
264                 return -EINVAL;
265
266         init_completion(&online_compl);
267
268         if (val)
269                 lpfc_workq_post_event(phba, &status, &online_compl,
270                                                         LPFC_EVT_ONLINE);
271         else
272                 lpfc_workq_post_event(phba, &status, &online_compl,
273                                                         LPFC_EVT_OFFLINE);
274         wait_for_completion(&online_compl);
275         if (!status)
276                 return strlen(buf);
277         else
278                 return -EIO;
279 }
280
281
282 #define lpfc_param_show(attr)   \
283 static ssize_t \
284 lpfc_##attr##_show(struct class_device *cdev, char *buf) \
285 { \
286         struct Scsi_Host *host = class_to_shost(cdev);\
287         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
288         int val = 0;\
289         val = phba->cfg_##attr;\
290         return snprintf(buf, PAGE_SIZE, "%d\n",\
291                         phba->cfg_##attr);\
292 }
293
294 #define lpfc_param_init(attr, default, minval, maxval)  \
295 static int \
296 lpfc_##attr##_init(struct lpfc_hba *phba, int val) \
297 { \
298         if (val >= minval && val <= maxval) {\
299                 phba->cfg_##attr = val;\
300                 return 0;\
301         }\
302         lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
303                         "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\
304                         "allowed range is ["#minval", "#maxval"]\n", \
305                         phba->brd_no, val); \
306         phba->cfg_##attr = default;\
307         return -EINVAL;\
308 }
309
310 #define lpfc_param_set(attr, default, minval, maxval)   \
311 static int \
312 lpfc_##attr##_set(struct lpfc_hba *phba, int val) \
313 { \
314         if (val >= minval && val <= maxval) {\
315                 phba->cfg_##attr = val;\
316                 return 0;\
317         }\
318         lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
319                         "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\
320                         "allowed range is ["#minval", "#maxval"]\n", \
321                         phba->brd_no, val); \
322         return -EINVAL;\
323 }
324
325 #define lpfc_param_store(attr)  \
326 static ssize_t \
327 lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
328 { \
329         struct Scsi_Host *host = class_to_shost(cdev);\
330         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
331         int val=0;\
332         if (sscanf(buf, "%d", &val) != 1)\
333         return -EPERM;\
334         if (lpfc_##attr##_set(phba, val) == 0) \
335                 return strlen(buf);\
336         else \
337                 return -EINVAL;\
338 }
339
340 #define LPFC_ATTR(name, defval, minval, maxval, desc) \
341 static int lpfc_##name = defval;\
342 module_param(lpfc_##name, int, 0);\
343 MODULE_PARM_DESC(lpfc_##name, desc);\
344 lpfc_param_init(name, defval, minval, maxval)
345
346 #define LPFC_ATTR_R(name, defval, minval, maxval, desc) \
347 static int lpfc_##name = defval;\
348 module_param(lpfc_##name, int, 0);\
349 MODULE_PARM_DESC(lpfc_##name, desc);\
350 lpfc_param_show(name)\
351 lpfc_param_init(name, defval, minval, maxval)\
352 static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
353
354 #define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \
355 static int lpfc_##name = defval;\
356 module_param(lpfc_##name, int, 0);\
357 MODULE_PARM_DESC(lpfc_##name, desc);\
358 lpfc_param_show(name)\
359 lpfc_param_init(name, defval, minval, maxval)\
360 lpfc_param_set(name, defval, minval, maxval)\
361 lpfc_param_store(name)\
362 static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
363                          lpfc_##name##_show, lpfc_##name##_store)
364
365 static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
366 static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
367 static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
368 static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
369 static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
370 static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_portnum_show, NULL);
371 static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
372 static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
373 static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL);
374 static CLASS_DEVICE_ATTR(option_rom_version, S_IRUGO,
375                                         lpfc_option_rom_version_show, NULL);
376 static CLASS_DEVICE_ATTR(num_discovered_ports, S_IRUGO,
377                                         lpfc_num_discovered_ports_show, NULL);
378 static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
379 static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
380                          NULL);
381 static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
382                          NULL);
383 static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
384                          lpfc_board_online_show, lpfc_board_online_store);
385
386
387 /*
388 # lpfc_log_verbose: Only turn this flag on if you are willing to risk being
389 # deluged with LOTS of information.
390 # You can set a bit mask to record specific types of verbose messages:
391 #
392 # LOG_ELS                       0x1        ELS events
393 # LOG_DISCOVERY                 0x2        Link discovery events
394 # LOG_MBOX                      0x4        Mailbox events
395 # LOG_INIT                      0x8        Initialization events
396 # LOG_LINK_EVENT                0x10       Link events
397 # LOG_IP                        0x20       IP traffic history
398 # LOG_FCP                       0x40       FCP traffic history
399 # LOG_NODE                      0x80       Node table events
400 # LOG_MISC                      0x400      Miscellaneous events
401 # LOG_SLI                       0x800      SLI events
402 # LOG_CHK_COND                  0x1000     FCP Check condition flag
403 # LOG_LIBDFC                    0x2000     LIBDFC events
404 # LOG_ALL_MSG                   0xffff     LOG all messages
405 */
406 LPFC_ATTR_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
407
408 /*
409 # lun_queue_depth:  This parameter is used to limit the number of outstanding
410 # commands per FCP LUN. Value range is [1,128]. Default value is 30.
411 */
412 LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,
413             "Max number of FCP commands we can queue to a specific LUN");
414
415 /*
416 # Some disk devices have a "select ID" or "select Target" capability.
417 # From a protocol standpoint "select ID" usually means select the
418 # Fibre channel "ALPA".  In the FC-AL Profile there is an "informative
419 # annex" which contains a table that maps a "select ID" (a number
420 # between 0 and 7F) to an ALPA.  By default, for compatibility with
421 # older drivers, the lpfc driver scans this table from low ALPA to high
422 # ALPA.
423 #
424 # Turning on the scan-down variable (on  = 1, off = 0) will
425 # cause the lpfc driver to use an inverted table, effectively
426 # scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.
427 #
428 # (Note: This "select ID" functionality is a LOOP ONLY characteristic
429 # and will not work across a fabric. Also this parameter will take
430 # effect only in the case when ALPA map is not available.)
431 */
432 LPFC_ATTR_R(scan_down, 1, 0, 1,
433              "Start scanning for devices from highest ALPA to lowest");
434
435 /*
436 # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
437 # until the timer expires. Value range is [0,255]. Default value is 20.
438 # NOTE: this MUST be less then the SCSI Layer command timeout - 1.
439 */
440 LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
441              "Seconds driver will hold I/O waiting for a device to come back");
442
443 /*
444 # lpfc_topology:  link topology for init link
445 #            0x0  = attempt loop mode then point-to-point
446 #            0x02 = attempt point-to-point mode only
447 #            0x04 = attempt loop mode only
448 #            0x06 = attempt point-to-point mode then loop
449 # Set point-to-point mode if you want to run as an N_Port.
450 # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
451 # Default value is 0.
452 */
453 LPFC_ATTR_R(topology, 0, 0, 6, "Select Fibre Channel topology");
454
455 /*
456 # lpfc_link_speed: Link speed selection for initializing the Fibre Channel
457 # connection.
458 #       0  = auto select (default)
459 #       1  = 1 Gigabaud
460 #       2  = 2 Gigabaud
461 #       4  = 4 Gigabaud
462 # Value range is [0,4]. Default value is 0.
463 */
464 LPFC_ATTR_R(link_speed, 0, 0, 4, "Select link speed");
465
466 /*
467 # lpfc_fcp_class:  Determines FC class to use for the FCP protocol.
468 # Value range is [2,3]. Default value is 3.
469 */
470 LPFC_ATTR_R(fcp_class, 3, 2, 3,
471              "Select Fibre Channel class of service for FCP sequences");
472
473 /*
474 # lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
475 # is [0,1]. Default value is 0.
476 */
477 LPFC_ATTR_RW(use_adisc, 0, 0, 1,
478              "Use ADISC on rediscovery to authenticate FCP devices");
479
480 /*
481 # lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
482 # range is [0,1]. Default value is 0.
483 */
484 LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
485
486 /*
487 # lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
488 # cr_delay (msec) or cr_count outstanding commands. cr_delay can take
489 # value [0,63]. cr_count can take value [0,255]. Default value of cr_delay
490 # is 0. Default value of cr_count is 1. The cr_count feature is disabled if
491 # cr_delay is set to 0.
492 */
493 LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
494                 "interrupt response is generated");
495
496 LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"
497                 "interrupt response is generated");
498
499 /*
500 # lpfc_fdmi_on: controls FDMI support.
501 #       0 = no FDMI support
502 #       1 = support FDMI without attribute of hostname
503 #       2 = support FDMI with attribute of hostname
504 # Value range [0,2]. Default value is 0.
505 */
506 LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
507
508 /*
509 # Specifies the maximum number of ELS cmds we can have outstanding (for
510 # discovery). Value range is [1,64]. Default value = 32.
511 */
512 LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands"
513                  "during discovery");
514
515 /*
516 # lpfc_max_luns: maximum number of LUNs per target driver will support
517 # Value range is [1,32768]. Default value is 256.
518 # NOTE: The SCSI layer will scan each target for this many luns
519 */
520 LPFC_ATTR_R(max_luns, 256, 1, 32768,
521              "Maximum number of LUNs per target driver will support");
522
523 struct class_device_attribute *lpfc_host_attrs[] = {
524         &class_device_attr_info,
525         &class_device_attr_serialnum,
526         &class_device_attr_modeldesc,
527         &class_device_attr_modelname,
528         &class_device_attr_programtype,
529         &class_device_attr_portnum,
530         &class_device_attr_fwrev,
531         &class_device_attr_hdw,
532         &class_device_attr_option_rom_version,
533         &class_device_attr_state,
534         &class_device_attr_num_discovered_ports,
535         &class_device_attr_lpfc_drvr_version,
536         &class_device_attr_lpfc_log_verbose,
537         &class_device_attr_lpfc_lun_queue_depth,
538         &class_device_attr_lpfc_nodev_tmo,
539         &class_device_attr_lpfc_fcp_class,
540         &class_device_attr_lpfc_use_adisc,
541         &class_device_attr_lpfc_ack0,
542         &class_device_attr_lpfc_topology,
543         &class_device_attr_lpfc_scan_down,
544         &class_device_attr_lpfc_link_speed,
545         &class_device_attr_lpfc_fdmi_on,
546         &class_device_attr_lpfc_max_luns,
547         &class_device_attr_nport_evt_cnt,
548         &class_device_attr_management_version,
549         &class_device_attr_board_online,
550         NULL,
551 };
552
553 static ssize_t
554 sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
555 {
556         size_t buf_off;
557         struct Scsi_Host *host = class_to_shost(container_of(kobj,
558                                              struct class_device, kobj));
559         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
560
561         if ((off + count) > FF_REG_AREA_SIZE)
562                 return -ERANGE;
563
564         if (count == 0) return 0;
565
566         if (off % 4 || count % 4 || (unsigned long)buf % 4)
567                 return -EINVAL;
568
569         spin_lock_irq(phba->host->host_lock);
570
571         if (!(phba->fc_flag & FC_OFFLINE_MODE)) {
572                 spin_unlock_irq(phba->host->host_lock);
573                 return -EPERM;
574         }
575
576         for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t))
577                 writel(*((uint32_t *)(buf + buf_off)),
578                        phba->ctrl_regs_memmap_p + off + buf_off);
579
580         spin_unlock_irq(phba->host->host_lock);
581
582         return count;
583 }
584
585 static ssize_t
586 sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
587 {
588         size_t buf_off;
589         uint32_t * tmp_ptr;
590         struct Scsi_Host *host = class_to_shost(container_of(kobj,
591                                              struct class_device, kobj));
592         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
593
594         if (off > FF_REG_AREA_SIZE)
595                 return -ERANGE;
596
597         if ((off + count) > FF_REG_AREA_SIZE)
598                 count = FF_REG_AREA_SIZE - off;
599
600         if (count == 0) return 0;
601
602         if (off % 4 || count % 4 || (unsigned long)buf % 4)
603                 return -EINVAL;
604
605         spin_lock_irq(phba->host->host_lock);
606
607         for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
608                 tmp_ptr = (uint32_t *)(buf + buf_off);
609                 *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
610         }
611
612         spin_unlock_irq(phba->host->host_lock);
613
614         return count;
615 }
616
617 static struct bin_attribute sysfs_ctlreg_attr = {
618         .attr = {
619                 .name = "ctlreg",
620                 .mode = S_IRUSR | S_IWUSR,
621                 .owner = THIS_MODULE,
622         },
623         .size = 256,
624         .read = sysfs_ctlreg_read,
625         .write = sysfs_ctlreg_write,
626 };
627
628
629 static void
630 sysfs_mbox_idle (struct lpfc_hba * phba)
631 {
632         phba->sysfs_mbox.state = SMBOX_IDLE;
633         phba->sysfs_mbox.offset = 0;
634
635         if (phba->sysfs_mbox.mbox) {
636                 mempool_free(phba->sysfs_mbox.mbox,
637                              phba->mbox_mem_pool);
638                 phba->sysfs_mbox.mbox = NULL;
639         }
640 }
641
642 static ssize_t
643 sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
644 {
645         struct Scsi_Host * host =
646                 class_to_shost(container_of(kobj, struct class_device, kobj));
647         struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata[0];
648         struct lpfcMboxq * mbox = NULL;
649
650         if ((count + off) > MAILBOX_CMD_SIZE)
651                 return -ERANGE;
652
653         if (off % 4 ||  count % 4 || (unsigned long)buf % 4)
654                 return -EINVAL;
655
656         if (count == 0)
657                 return 0;
658
659         if (off == 0) {
660                 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
661                 if (!mbox)
662                         return -ENOMEM;
663
664         }
665
666         spin_lock_irq(host->host_lock);
667
668         if (off == 0) {
669                 if (phba->sysfs_mbox.mbox)
670                         mempool_free(mbox, phba->mbox_mem_pool);
671                 else
672                         phba->sysfs_mbox.mbox = mbox;
673                 phba->sysfs_mbox.state = SMBOX_WRITING;
674         } else {
675                 if (phba->sysfs_mbox.state  != SMBOX_WRITING ||
676                     phba->sysfs_mbox.offset != off           ||
677                     phba->sysfs_mbox.mbox   == NULL ) {
678                         sysfs_mbox_idle(phba);
679                         spin_unlock_irq(host->host_lock);
680                         return -EINVAL;
681                 }
682         }
683
684         memcpy((uint8_t *) & phba->sysfs_mbox.mbox->mb + off,
685                buf, count);
686
687         phba->sysfs_mbox.offset = off + count;
688
689         spin_unlock_irq(host->host_lock);
690
691         return count;
692 }
693
694 static ssize_t
695 sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
696 {
697         struct Scsi_Host *host =
698                 class_to_shost(container_of(kobj, struct class_device,
699                                             kobj));
700         struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
701         int rc;
702
703         if (off > sizeof(MAILBOX_t))
704                 return -ERANGE;
705
706         if ((count + off) > sizeof(MAILBOX_t))
707                 count = sizeof(MAILBOX_t) - off;
708
709         if (off % 4 ||  count % 4 || (unsigned long)buf % 4)
710                 return -EINVAL;
711
712         if (off && count == 0)
713                 return 0;
714
715         spin_lock_irq(phba->host->host_lock);
716
717         if (off == 0 &&
718             phba->sysfs_mbox.state  == SMBOX_WRITING &&
719             phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) {
720
721                 switch (phba->sysfs_mbox.mbox->mb.mbxCommand) {
722                         /* Offline only */
723                 case MBX_WRITE_NV:
724                 case MBX_INIT_LINK:
725                 case MBX_DOWN_LINK:
726                 case MBX_CONFIG_LINK:
727                 case MBX_CONFIG_RING:
728                 case MBX_RESET_RING:
729                 case MBX_UNREG_LOGIN:
730                 case MBX_CLEAR_LA:
731                 case MBX_DUMP_CONTEXT:
732                 case MBX_RUN_DIAGS:
733                 case MBX_RESTART:
734                 case MBX_FLASH_WR_ULA:
735                 case MBX_SET_MASK:
736                 case MBX_SET_SLIM:
737                 case MBX_SET_DEBUG:
738                         if (!(phba->fc_flag & FC_OFFLINE_MODE)) {
739                                 printk(KERN_WARNING "mbox_read:Command 0x%x "
740                                        "is illegal in on-line state\n",
741                                        phba->sysfs_mbox.mbox->mb.mbxCommand);
742                                 sysfs_mbox_idle(phba);
743                                 spin_unlock_irq(phba->host->host_lock);
744                                 return -EPERM;
745                         }
746                 case MBX_LOAD_SM:
747                 case MBX_READ_NV:
748                 case MBX_READ_CONFIG:
749                 case MBX_READ_RCONFIG:
750                 case MBX_READ_STATUS:
751                 case MBX_READ_XRI:
752                 case MBX_READ_REV:
753                 case MBX_READ_LNK_STAT:
754                 case MBX_DUMP_MEMORY:
755                 case MBX_DOWN_LOAD:
756                 case MBX_UPDATE_CFG:
757                 case MBX_LOAD_AREA:
758                 case MBX_LOAD_EXP_ROM:
759                         break;
760                 case MBX_READ_SPARM64:
761                 case MBX_READ_LA:
762                 case MBX_READ_LA64:
763                 case MBX_REG_LOGIN:
764                 case MBX_REG_LOGIN64:
765                 case MBX_CONFIG_PORT:
766                 case MBX_RUN_BIU_DIAG:
767                         printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n",
768                                phba->sysfs_mbox.mbox->mb.mbxCommand);
769                         sysfs_mbox_idle(phba);
770                         spin_unlock_irq(phba->host->host_lock);
771                         return -EPERM;
772                 default:
773                         printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n",
774                                phba->sysfs_mbox.mbox->mb.mbxCommand);
775                         sysfs_mbox_idle(phba);
776                         spin_unlock_irq(phba->host->host_lock);
777                         return -EPERM;
778                 }
779
780                 if ((phba->fc_flag & FC_OFFLINE_MODE) ||
781                     (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){
782
783                         spin_unlock_irq(phba->host->host_lock);
784                         rc = lpfc_sli_issue_mbox (phba,
785                                                   phba->sysfs_mbox.mbox,
786                                                   MBX_POLL);
787                         spin_lock_irq(phba->host->host_lock);
788
789                 } else {
790                         spin_unlock_irq(phba->host->host_lock);
791                         rc = lpfc_sli_issue_mbox_wait (phba,
792                                                        phba->sysfs_mbox.mbox,
793                                                        phba->fc_ratov * 2);
794                         spin_lock_irq(phba->host->host_lock);
795                 }
796
797                 if (rc != MBX_SUCCESS) {
798                         sysfs_mbox_idle(phba);
799                         spin_unlock_irq(host->host_lock);
800                         return -ENODEV;
801                 }
802                 phba->sysfs_mbox.state = SMBOX_READING;
803         }
804         else if (phba->sysfs_mbox.offset != off ||
805                  phba->sysfs_mbox.state  != SMBOX_READING) {
806                 printk(KERN_WARNING  "mbox_read: Bad State\n");
807                 sysfs_mbox_idle(phba);
808                 spin_unlock_irq(host->host_lock);
809                 return -EINVAL;
810         }
811
812         memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count);
813
814         phba->sysfs_mbox.offset = off + count;
815
816         if (phba->sysfs_mbox.offset == sizeof(MAILBOX_t))
817                 sysfs_mbox_idle(phba);
818
819         spin_unlock_irq(phba->host->host_lock);
820
821         return count;
822 }
823
824 static struct bin_attribute sysfs_mbox_attr = {
825         .attr = {
826                 .name = "mbox",
827                 .mode = S_IRUSR | S_IWUSR,
828                 .owner = THIS_MODULE,
829         },
830         .size = sizeof(MAILBOX_t),
831         .read = sysfs_mbox_read,
832         .write = sysfs_mbox_write,
833 };
834
835 int
836 lpfc_alloc_sysfs_attr(struct lpfc_hba *phba)
837 {
838         struct Scsi_Host *host = phba->host;
839         int error;
840
841         error = sysfs_create_bin_file(&host->shost_classdev.kobj,
842                                                         &sysfs_ctlreg_attr);
843         if (error)
844                 goto out;
845
846         error = sysfs_create_bin_file(&host->shost_classdev.kobj,
847                                                         &sysfs_mbox_attr);
848         if (error)
849                 goto out_remove_ctlreg_attr;
850
851         return 0;
852 out_remove_ctlreg_attr:
853         sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);
854 out:
855         return error;
856 }
857
858 void
859 lpfc_free_sysfs_attr(struct lpfc_hba *phba)
860 {
861         struct Scsi_Host *host = phba->host;
862
863         sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_mbox_attr);
864         sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);
865 }
866
867
868 /*
869  * Dynamic FC Host Attributes Support
870  */
871
872 static void
873 lpfc_get_host_port_id(struct Scsi_Host *shost)
874 {
875         struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
876         /* note: fc_myDID already in cpu endianness */
877         fc_host_port_id(shost) = phba->fc_myDID;
878 }
879
880 static void
881 lpfc_get_host_port_type(struct Scsi_Host *shost)
882 {
883         struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
884
885         spin_lock_irq(shost->host_lock);
886
887         if (phba->hba_state == LPFC_HBA_READY) {
888                 if (phba->fc_topology == TOPOLOGY_LOOP) {
889                         if (phba->fc_flag & FC_PUBLIC_LOOP)
890                                 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
891                         else
892                                 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
893                 } else {
894                         if (phba->fc_flag & FC_FABRIC)
895                                 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
896                         else
897                                 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
898                 }
899         } else
900                 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
901
902         spin_unlock_irq(shost->host_lock);
903 }
904
905 static void
906 lpfc_get_host_port_state(struct Scsi_Host *shost)
907 {
908         struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
909
910         spin_lock_irq(shost->host_lock);
911
912         if (phba->fc_flag & FC_OFFLINE_MODE)
913                 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
914         else {
915                 switch (phba->hba_state) {
916                 case LPFC_INIT_START:
917                 case LPFC_INIT_MBX_CMDS:
918                 case LPFC_LINK_DOWN:
919                         fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
920                         break;
921                 case LPFC_LINK_UP:
922                 case LPFC_LOCAL_CFG_LINK:
923                 case LPFC_FLOGI:
924                 case LPFC_FABRIC_CFG_LINK:
925                 case LPFC_NS_REG:
926                 case LPFC_NS_QRY:
927                 case LPFC_BUILD_DISC_LIST:
928                 case LPFC_DISC_AUTH:
929                 case LPFC_CLEAR_LA:
930                 case LPFC_HBA_READY:
931                         /* Links up, beyond this port_type reports state */
932                         fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
933                         break;
934                 case LPFC_HBA_ERROR:
935                         fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
936                         break;
937                 default:
938                         fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
939                         break;
940                 }
941         }
942
943         spin_unlock_irq(shost->host_lock);
944 }
945
946 static void
947 lpfc_get_host_speed(struct Scsi_Host *shost)
948 {
949         struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
950
951         spin_lock_irq(shost->host_lock);
952
953         if (phba->hba_state == LPFC_HBA_READY) {
954                 switch(phba->fc_linkspeed) {
955                         case LA_1GHZ_LINK:
956                                 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
957                         break;
958                         case LA_2GHZ_LINK:
959                                 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
960                         break;
961                         case LA_4GHZ_LINK:
962                                 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
963                         break;
964                         default:
965                                 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
966                         break;
967                 }
968         }
969
970         spin_unlock_irq(shost->host_lock);
971 }
972
973 static void
974 lpfc_get_host_fabric_name (struct Scsi_Host *shost)
975 {
976         struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
977         u64 node_name;
978
979         spin_lock_irq(shost->host_lock);
980
981         if ((phba->fc_flag & FC_FABRIC) ||
982             ((phba->fc_topology == TOPOLOGY_LOOP) &&
983              (phba->fc_flag & FC_PUBLIC_LOOP)))
984                 node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
985         else
986                 /* fabric is local port if there is no F/FL_Port */
987                 node_name = wwn_to_u64(phba->fc_nodename.u.wwn);
988
989         spin_unlock_irq(shost->host_lock);
990
991         fc_host_fabric_name(shost) = node_name;
992 }
993
994
995 static struct fc_host_statistics *
996 lpfc_get_stats(struct Scsi_Host *shost)
997 {
998         struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
999         struct lpfc_sli *psli = &phba->sli;
1000         struct fc_host_statistics *hs = &phba->link_stats;
1001         LPFC_MBOXQ_t *pmboxq;
1002         MAILBOX_t *pmb;
1003         int rc = 0;
1004
1005         pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1006         if (!pmboxq)
1007                 return NULL;
1008         memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1009
1010         pmb = &pmboxq->mb;
1011         pmb->mbxCommand = MBX_READ_STATUS;
1012         pmb->mbxOwner = OWN_HOST;
1013         pmboxq->context1 = NULL;
1014
1015         if ((phba->fc_flag & FC_OFFLINE_MODE) ||
1016                 (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
1017                 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
1018         else
1019                 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1020
1021         if (rc != MBX_SUCCESS) {
1022                 if (rc == MBX_TIMEOUT)
1023                         pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1024                 else
1025                         mempool_free(pmboxq, phba->mbox_mem_pool);
1026                 return NULL;
1027         }
1028
1029         memset(hs, 0, sizeof (struct fc_host_statistics));
1030
1031         hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
1032         hs->tx_words = (pmb->un.varRdStatus.xmitByteCnt * 256);
1033         hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
1034         hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256);
1035
1036         memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1037         pmb->mbxCommand = MBX_READ_LNK_STAT;
1038         pmb->mbxOwner = OWN_HOST;
1039         pmboxq->context1 = NULL;
1040
1041         if ((phba->fc_flag & FC_OFFLINE_MODE) ||
1042             (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
1043                 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
1044         else
1045                 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1046
1047         if (rc != MBX_SUCCESS) {
1048                 if (rc == MBX_TIMEOUT)
1049                         pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1050                 else
1051                         mempool_free( pmboxq, phba->mbox_mem_pool);
1052                 return NULL;
1053         }
1054
1055         hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
1056         hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
1057         hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
1058         hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
1059         hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
1060         hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
1061         hs->error_frames = pmb->un.varRdLnk.crcCnt;
1062
1063         if (phba->fc_topology == TOPOLOGY_LOOP) {
1064                 hs->lip_count = (phba->fc_eventTag >> 1);
1065                 hs->nos_count = -1;
1066         } else {
1067                 hs->lip_count = -1;
1068                 hs->nos_count = (phba->fc_eventTag >> 1);
1069         }
1070
1071         hs->dumped_frames = -1;
1072
1073 /* FIX ME */
1074         /*hs->SecondsSinceLastReset = (jiffies - lpfc_loadtime) / HZ;*/
1075
1076         return hs;
1077 }
1078
1079
1080 /*
1081  * The LPFC driver treats linkdown handling as target loss events so there
1082  * are no sysfs handlers for link_down_tmo.
1083  */
1084 static void
1085 lpfc_get_starget_port_id(struct scsi_target *starget)
1086 {
1087         struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
1088         struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
1089         uint32_t did = -1;
1090         struct lpfc_nodelist *ndlp = NULL;
1091
1092         spin_lock_irq(shost->host_lock);
1093         /* Search the mapped list for this target ID */
1094         list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
1095                 if (starget->id == ndlp->nlp_sid) {
1096                         did = ndlp->nlp_DID;
1097                         break;
1098                 }
1099         }
1100         spin_unlock_irq(shost->host_lock);
1101
1102         fc_starget_port_id(starget) = did;
1103 }
1104
1105 static void
1106 lpfc_get_starget_node_name(struct scsi_target *starget)
1107 {
1108         struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
1109         struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
1110         u64 node_name = 0;
1111         struct lpfc_nodelist *ndlp = NULL;
1112
1113         spin_lock_irq(shost->host_lock);
1114         /* Search the mapped list for this target ID */
1115         list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
1116                 if (starget->id == ndlp->nlp_sid) {
1117                         node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
1118                         break;
1119                 }
1120         }
1121         spin_unlock_irq(shost->host_lock);
1122
1123         fc_starget_node_name(starget) = node_name;
1124 }
1125
1126 static void
1127 lpfc_get_starget_port_name(struct scsi_target *starget)
1128 {
1129         struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
1130         struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
1131         u64 port_name = 0;
1132         struct lpfc_nodelist *ndlp = NULL;
1133
1134         spin_lock_irq(shost->host_lock);
1135         /* Search the mapped list for this target ID */
1136         list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
1137                 if (starget->id == ndlp->nlp_sid) {
1138                         port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
1139                         break;
1140                 }
1141         }
1142         spin_unlock_irq(shost->host_lock);
1143
1144         fc_starget_port_name(starget) = port_name;
1145 }
1146
1147 static void
1148 lpfc_get_rport_loss_tmo(struct fc_rport *rport)
1149 {
1150         /*
1151          * Return the driver's global value for device loss timeout plus
1152          * five seconds to allow the driver's nodev timer to run.
1153          */
1154         rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
1155 }
1156
1157 static void
1158 lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
1159 {
1160         /*
1161          * The driver doesn't have a per-target timeout setting.  Set
1162          * this value globally. lpfc_nodev_tmo should be greater then 0.
1163          */
1164         if (timeout)
1165                 lpfc_nodev_tmo = timeout;
1166         else
1167                 lpfc_nodev_tmo = 1;
1168         rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
1169 }
1170
1171
1172 #define lpfc_rport_show_function(field, format_string, sz, cast)        \
1173 static ssize_t                                                          \
1174 lpfc_show_rport_##field (struct class_device *cdev, char *buf)          \
1175 {                                                                       \
1176         struct fc_rport *rport = transport_class_to_rport(cdev);        \
1177         struct lpfc_rport_data *rdata = rport->hostdata;                \
1178         return snprintf(buf, sz, format_string,                         \
1179                 (rdata->target) ? cast rdata->target->field : 0);       \
1180 }
1181
1182 #define lpfc_rport_rd_attr(field, format_string, sz)                    \
1183         lpfc_rport_show_function(field, format_string, sz, )            \
1184 static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
1185
1186
1187 struct fc_function_template lpfc_transport_functions = {
1188         /* fixed attributes the driver supports */
1189         .show_host_node_name = 1,
1190         .show_host_port_name = 1,
1191         .show_host_supported_classes = 1,
1192         .show_host_supported_fc4s = 1,
1193         .show_host_symbolic_name = 1,
1194         .show_host_supported_speeds = 1,
1195         .show_host_maxframe_size = 1,
1196
1197         /* dynamic attributes the driver supports */
1198         .get_host_port_id = lpfc_get_host_port_id,
1199         .show_host_port_id = 1,
1200
1201         .get_host_port_type = lpfc_get_host_port_type,
1202         .show_host_port_type = 1,
1203
1204         .get_host_port_state = lpfc_get_host_port_state,
1205         .show_host_port_state = 1,
1206
1207         /* active_fc4s is shown but doesn't change (thus no get function) */
1208         .show_host_active_fc4s = 1,
1209
1210         .get_host_speed = lpfc_get_host_speed,
1211         .show_host_speed = 1,
1212
1213         .get_host_fabric_name = lpfc_get_host_fabric_name,
1214         .show_host_fabric_name = 1,
1215
1216         /*
1217          * The LPFC driver treats linkdown handling as target loss events
1218          * so there are no sysfs handlers for link_down_tmo.
1219          */
1220
1221         .get_fc_host_stats = lpfc_get_stats,
1222
1223         /* the LPFC driver doesn't support resetting stats yet */
1224
1225         .dd_fcrport_size = sizeof(struct lpfc_rport_data),
1226         .show_rport_maxframe_size = 1,
1227         .show_rport_supported_classes = 1,
1228
1229         .get_rport_dev_loss_tmo = lpfc_get_rport_loss_tmo,
1230         .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
1231         .show_rport_dev_loss_tmo = 1,
1232
1233         .get_starget_port_id  = lpfc_get_starget_port_id,
1234         .show_starget_port_id = 1,
1235
1236         .get_starget_node_name = lpfc_get_starget_node_name,
1237         .show_starget_node_name = 1,
1238
1239         .get_starget_port_name = lpfc_get_starget_port_name,
1240         .show_starget_port_name = 1,
1241
1242         .issue_fc_host_lip = lpfc_issue_lip,
1243 };
1244
1245 void
1246 lpfc_get_cfgparam(struct lpfc_hba *phba)
1247 {
1248         lpfc_log_verbose_init(phba, lpfc_log_verbose);
1249         lpfc_cr_delay_init(phba, lpfc_cr_delay);
1250         lpfc_cr_count_init(phba, lpfc_cr_count);
1251         lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
1252         lpfc_fcp_class_init(phba, lpfc_fcp_class);
1253         lpfc_use_adisc_init(phba, lpfc_use_adisc);
1254         lpfc_ack0_init(phba, lpfc_ack0);
1255         lpfc_topology_init(phba, lpfc_topology);
1256         lpfc_scan_down_init(phba, lpfc_scan_down);
1257         lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
1258         lpfc_link_speed_init(phba, lpfc_link_speed);
1259         lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
1260         lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
1261         lpfc_max_luns_init(phba, lpfc_max_luns);
1262
1263         /*
1264          * The total number of segments is the configuration value plus 2
1265          * since the IOCB need a command and response bde.
1266          */
1267         phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2;
1268
1269         /*
1270          * Since the sg_tablesize is module parameter, the sg_dma_buf_size
1271          * used to create the sg_dma_buf_pool must be dynamically calculated
1272          */
1273         phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
1274                         sizeof(struct fcp_rsp) +
1275                         (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64));
1276
1277         switch (phba->pcidev->device) {
1278         case PCI_DEVICE_ID_LP101:
1279         case PCI_DEVICE_ID_BSMB:
1280         case PCI_DEVICE_ID_ZSMB:
1281                 phba->cfg_hba_queue_depth = LPFC_LP101_HBA_Q_DEPTH;
1282                 break;
1283         case PCI_DEVICE_ID_RFLY:
1284         case PCI_DEVICE_ID_PFLY:
1285         case PCI_DEVICE_ID_BMID:
1286         case PCI_DEVICE_ID_ZMID:
1287         case PCI_DEVICE_ID_TFLY:
1288                 phba->cfg_hba_queue_depth = LPFC_LC_HBA_Q_DEPTH;
1289                 break;
1290         default:
1291                 phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH;
1292         }
1293         return;
1294 }