aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_attr.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c201
1 files changed, 120 insertions, 81 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index acae7c48ef7d..89e8222bc7cc 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -200,19 +200,13 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
200} 200}
201 201
202 202
203static ssize_t 203static int
204lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count) 204lpfc_issue_lip(struct Scsi_Host *host)
205{ 205{
206 struct Scsi_Host *host = class_to_shost(cdev);
207 struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0]; 206 struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
208 int val = 0;
209 LPFC_MBOXQ_t *pmboxq; 207 LPFC_MBOXQ_t *pmboxq;
210 int mbxstatus = MBXERR_ERROR; 208 int mbxstatus = MBXERR_ERROR;
211 209
212 if ((sscanf(buf, "%d", &val) != 1) ||
213 (val != 1))
214 return -EINVAL;
215
216 if ((phba->fc_flag & FC_OFFLINE_MODE) || 210 if ((phba->fc_flag & FC_OFFLINE_MODE) ||
217 (phba->hba_state != LPFC_HBA_READY)) 211 (phba->hba_state != LPFC_HBA_READY))
218 return -EPERM; 212 return -EPERM;
@@ -229,12 +223,12 @@ lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
229 if (mbxstatus == MBX_TIMEOUT) 223 if (mbxstatus == MBX_TIMEOUT)
230 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 224 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
231 else 225 else
232 mempool_free( pmboxq, phba->mbox_mem_pool); 226 mempool_free(pmboxq, phba->mbox_mem_pool);
233 227
234 if (mbxstatus == MBXERR_ERROR) 228 if (mbxstatus == MBXERR_ERROR)
235 return -EIO; 229 return -EIO;
236 230
237 return strlen(buf); 231 return 0;
238} 232}
239 233
240static ssize_t 234static ssize_t
@@ -251,8 +245,6 @@ lpfc_board_online_show(struct class_device *cdev, char *buf)
251 struct Scsi_Host *host = class_to_shost(cdev); 245 struct Scsi_Host *host = class_to_shost(cdev);
252 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0]; 246 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
253 247
254 if (!phba) return 0;
255
256 if (phba->fc_flag & FC_OFFLINE_MODE) 248 if (phba->fc_flag & FC_OFFLINE_MODE)
257 return snprintf(buf, PAGE_SIZE, "0\n"); 249 return snprintf(buf, PAGE_SIZE, "0\n");
258 else 250 else
@@ -269,7 +261,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
269 int val=0, status=0; 261 int val=0, status=0;
270 262
271 if (sscanf(buf, "%d", &val) != 1) 263 if (sscanf(buf, "%d", &val) != 1)
272 return 0; 264 return -EINVAL;
273 265
274 init_completion(&online_compl); 266 init_completion(&online_compl);
275 267
@@ -283,7 +275,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
283 if (!status) 275 if (!status)
284 return strlen(buf); 276 return strlen(buf);
285 else 277 else
286 return 0; 278 return -EIO;
287} 279}
288 280
289 281
@@ -294,47 +286,83 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \
294 struct Scsi_Host *host = class_to_shost(cdev);\ 286 struct Scsi_Host *host = class_to_shost(cdev);\
295 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ 287 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
296 int val = 0;\ 288 int val = 0;\
297 if (phba){\ 289 val = phba->cfg_##attr;\
298 val = phba->cfg_##attr;\ 290 return snprintf(buf, PAGE_SIZE, "%d\n",\
299 return snprintf(buf, PAGE_SIZE, "%d\n",\ 291 phba->cfg_##attr);\
300 phba->cfg_##attr);\ 292}
293
294#define lpfc_param_hex_show(attr) \
295static ssize_t \
296lpfc_##attr##_show(struct class_device *cdev, char *buf) \
297{ \
298 struct Scsi_Host *host = class_to_shost(cdev);\
299 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
300 int val = 0;\
301 val = phba->cfg_##attr;\
302 return snprintf(buf, PAGE_SIZE, "%#x\n",\
303 phba->cfg_##attr);\
304}
305
306#define lpfc_param_init(attr, default, minval, maxval) \
307static int \
308lpfc_##attr##_init(struct lpfc_hba *phba, int val) \
309{ \
310 if (val >= minval && val <= maxval) {\
311 phba->cfg_##attr = val;\
312 return 0;\
301 }\ 313 }\
302 return 0;\ 314 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
315 "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\
316 "allowed range is ["#minval", "#maxval"]\n", \
317 phba->brd_no, val); \
318 phba->cfg_##attr = default;\
319 return -EINVAL;\
303} 320}
304 321
305#define lpfc_param_store(attr, minval, maxval) \ 322#define lpfc_param_set(attr, default, minval, maxval) \
323static int \
324lpfc_##attr##_set(struct lpfc_hba *phba, int val) \
325{ \
326 if (val >= minval && val <= maxval) {\
327 phba->cfg_##attr = val;\
328 return 0;\
329 }\
330 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
331 "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\
332 "allowed range is ["#minval", "#maxval"]\n", \
333 phba->brd_no, val); \
334 return -EINVAL;\
335}
336
337#define lpfc_param_store(attr) \
306static ssize_t \ 338static ssize_t \
307lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ 339lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
308{ \ 340{ \
309 struct Scsi_Host *host = class_to_shost(cdev);\ 341 struct Scsi_Host *host = class_to_shost(cdev);\
310 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ 342 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
311 int val = 0;\ 343 int val=0;\
312 if (!isdigit(buf[0]))\ 344 if (!isdigit(buf[0]))\
313 return -EINVAL;\ 345 return -EINVAL;\
314 if (sscanf(buf, "0x%x", &val) != 1)\ 346 if (sscanf(buf, "%i", &val) != 1)\
315 if (sscanf(buf, "%d", &val) != 1)\ 347 return -EINVAL;\
316 return -EINVAL;\ 348 if (lpfc_##attr##_set(phba, val) == 0) \
317 if (phba){\ 349 return strlen(buf);\
318 if (val >= minval && val <= maxval) {\ 350 else \
319 phba->cfg_##attr = val;\ 351 return -EINVAL;\
320 return strlen(buf);\
321 }\
322 }\
323 return 0;\
324} 352}
325 353
326#define LPFC_ATTR_R_NOINIT(name, desc) \ 354#define LPFC_ATTR(name, defval, minval, maxval, desc) \
327extern int lpfc_##name;\ 355static int lpfc_##name = defval;\
328module_param(lpfc_##name, int, 0);\ 356module_param(lpfc_##name, int, 0);\
329MODULE_PARM_DESC(lpfc_##name, desc);\ 357MODULE_PARM_DESC(lpfc_##name, desc);\
330lpfc_param_show(name)\ 358lpfc_param_init(name, defval, minval, maxval)
331static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
332 359
333#define LPFC_ATTR_R(name, defval, minval, maxval, desc) \ 360#define LPFC_ATTR_R(name, defval, minval, maxval, desc) \
334static int lpfc_##name = defval;\ 361static int lpfc_##name = defval;\
335module_param(lpfc_##name, int, 0);\ 362module_param(lpfc_##name, int, 0);\
336MODULE_PARM_DESC(lpfc_##name, desc);\ 363MODULE_PARM_DESC(lpfc_##name, desc);\
337lpfc_param_show(name)\ 364lpfc_param_show(name)\
365lpfc_param_init(name, defval, minval, maxval)\
338static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) 366static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
339 367
340#define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \ 368#define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \
@@ -342,7 +370,28 @@ static int lpfc_##name = defval;\
342module_param(lpfc_##name, int, 0);\ 370module_param(lpfc_##name, int, 0);\
343MODULE_PARM_DESC(lpfc_##name, desc);\ 371MODULE_PARM_DESC(lpfc_##name, desc);\
344lpfc_param_show(name)\ 372lpfc_param_show(name)\
345lpfc_param_store(name, minval, maxval)\ 373lpfc_param_init(name, defval, minval, maxval)\
374lpfc_param_set(name, defval, minval, maxval)\
375lpfc_param_store(name)\
376static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
377 lpfc_##name##_show, lpfc_##name##_store)
378
379#define LPFC_ATTR_HEX_R(name, defval, minval, maxval, desc) \
380static int lpfc_##name = defval;\
381module_param(lpfc_##name, int, 0);\
382MODULE_PARM_DESC(lpfc_##name, desc);\
383lpfc_param_hex_show(name)\
384lpfc_param_init(name, defval, minval, maxval)\
385static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
386
387#define LPFC_ATTR_HEX_RW(name, defval, minval, maxval, desc) \
388static int lpfc_##name = defval;\
389module_param(lpfc_##name, int, 0);\
390MODULE_PARM_DESC(lpfc_##name, desc);\
391lpfc_param_hex_show(name)\
392lpfc_param_init(name, defval, minval, maxval)\
393lpfc_param_set(name, defval, minval, maxval)\
394lpfc_param_store(name)\
346static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ 395static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
347 lpfc_##name##_show, lpfc_##name##_store) 396 lpfc_##name##_show, lpfc_##name##_store)
348 397
@@ -364,7 +413,6 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
364 NULL); 413 NULL);
365static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, 414static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
366 NULL); 415 NULL);
367static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
368static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, 416static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
369 lpfc_board_online_show, lpfc_board_online_store); 417 lpfc_board_online_show, lpfc_board_online_store);
370 418
@@ -388,7 +436,7 @@ static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
388# LOG_LIBDFC 0x2000 LIBDFC events 436# LOG_LIBDFC 0x2000 LIBDFC events
389# LOG_ALL_MSG 0xffff LOG all messages 437# LOG_ALL_MSG 0xffff LOG all messages
390*/ 438*/
391LPFC_ATTR_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask"); 439LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
392 440
393/* 441/*
394# lun_queue_depth: This parameter is used to limit the number of outstanding 442# lun_queue_depth: This parameter is used to limit the number of outstanding
@@ -419,7 +467,7 @@ LPFC_ATTR_R(scan_down, 1, 0, 1,
419 467
420/* 468/*
421# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear 469# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
422# until the timer expires. Value range is [0,255]. Default value is 20. 470# until the timer expires. Value range is [0,255]. Default value is 30.
423# NOTE: this MUST be less then the SCSI Layer command timeout - 1. 471# NOTE: this MUST be less then the SCSI Layer command timeout - 1.
424*/ 472*/
425LPFC_ATTR_RW(nodev_tmo, 30, 0, 255, 473LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
@@ -475,14 +523,10 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
475# is 0. Default value of cr_count is 1. The cr_count feature is disabled if 523# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
476# cr_delay is set to 0. 524# cr_delay is set to 0.
477*/ 525*/
478static int lpfc_cr_delay = 0; 526LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
479module_param(lpfc_cr_delay, int , 0);
480MODULE_PARM_DESC(lpfc_cr_delay, "A count of milliseconds after which an "
481 "interrupt response is generated"); 527 "interrupt response is generated");
482 528
483static int lpfc_cr_count = 1; 529LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"
484module_param(lpfc_cr_count, int, 0);
485MODULE_PARM_DESC(lpfc_cr_count, "A count of I/O completions after which an "
486 "interrupt response is generated"); 530 "interrupt response is generated");
487 531
488/* 532/*
@@ -498,9 +542,7 @@ LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
498# Specifies the maximum number of ELS cmds we can have outstanding (for 542# Specifies the maximum number of ELS cmds we can have outstanding (for
499# discovery). Value range is [1,64]. Default value = 32. 543# discovery). Value range is [1,64]. Default value = 32.
500*/ 544*/
501static int lpfc_discovery_threads = 32; 545LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands"
502module_param(lpfc_discovery_threads, int, 0);
503MODULE_PARM_DESC(lpfc_discovery_threads, "Maximum number of ELS commands "
504 "during discovery"); 546 "during discovery");
505 547
506/* 548/*
@@ -537,7 +579,6 @@ struct class_device_attribute *lpfc_host_attrs[] = {
537 &class_device_attr_lpfc_max_luns, 579 &class_device_attr_lpfc_max_luns,
538 &class_device_attr_nport_evt_cnt, 580 &class_device_attr_nport_evt_cnt,
539 &class_device_attr_management_version, 581 &class_device_attr_management_version,
540 &class_device_attr_issue_lip,
541 &class_device_attr_board_online, 582 &class_device_attr_board_online,
542 NULL, 583 NULL,
543}; 584};
@@ -992,7 +1033,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
992 struct fc_host_statistics *hs = &phba->link_stats; 1033 struct fc_host_statistics *hs = &phba->link_stats;
993 LPFC_MBOXQ_t *pmboxq; 1034 LPFC_MBOXQ_t *pmboxq;
994 MAILBOX_t *pmb; 1035 MAILBOX_t *pmb;
995 int rc=0; 1036 int rc = 0;
996 1037
997 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 1038 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
998 if (!pmboxq) 1039 if (!pmboxq)
@@ -1005,18 +1046,16 @@ lpfc_get_stats(struct Scsi_Host *shost)
1005 pmboxq->context1 = NULL; 1046 pmboxq->context1 = NULL;
1006 1047
1007 if ((phba->fc_flag & FC_OFFLINE_MODE) || 1048 if ((phba->fc_flag & FC_OFFLINE_MODE) ||
1008 (!(psli->sli_flag & LPFC_SLI2_ACTIVE))){ 1049 (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
1009 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); 1050 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
1010 } else 1051 else
1011 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 1052 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1012 1053
1013 if (rc != MBX_SUCCESS) { 1054 if (rc != MBX_SUCCESS) {
1014 if (pmboxq) { 1055 if (rc == MBX_TIMEOUT)
1015 if (rc == MBX_TIMEOUT) 1056 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1016 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 1057 else
1017 else 1058 mempool_free(pmboxq, phba->mbox_mem_pool);
1018 mempool_free( pmboxq, phba->mbox_mem_pool);
1019 }
1020 return NULL; 1059 return NULL;
1021 } 1060 }
1022 1061
@@ -1027,24 +1066,22 @@ lpfc_get_stats(struct Scsi_Host *shost)
1027 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt; 1066 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
1028 hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256); 1067 hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256);
1029 1068
1030 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); 1069 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1031 pmb->mbxCommand = MBX_READ_LNK_STAT; 1070 pmb->mbxCommand = MBX_READ_LNK_STAT;
1032 pmb->mbxOwner = OWN_HOST; 1071 pmb->mbxOwner = OWN_HOST;
1033 pmboxq->context1 = NULL; 1072 pmboxq->context1 = NULL;
1034 1073
1035 if ((phba->fc_flag & FC_OFFLINE_MODE) || 1074 if ((phba->fc_flag & FC_OFFLINE_MODE) ||
1036 (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) { 1075 (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
1037 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); 1076 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
1038 } else 1077 else
1039 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); 1078 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1040 1079
1041 if (rc != MBX_SUCCESS) { 1080 if (rc != MBX_SUCCESS) {
1042 if (pmboxq) { 1081 if (rc == MBX_TIMEOUT)
1043 if (rc == MBX_TIMEOUT) 1082 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1044 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 1083 else
1045 else 1084 mempool_free( pmboxq, phba->mbox_mem_pool);
1046 mempool_free( pmboxq, phba->mbox_mem_pool);
1047 }
1048 return NULL; 1085 return NULL;
1049 } 1086 }
1050 1087
@@ -1234,25 +1271,27 @@ struct fc_function_template lpfc_transport_functions = {
1234 1271
1235 .get_starget_port_name = lpfc_get_starget_port_name, 1272 .get_starget_port_name = lpfc_get_starget_port_name,
1236 .show_starget_port_name = 1, 1273 .show_starget_port_name = 1,
1274
1275 .issue_fc_host_lip = lpfc_issue_lip,
1237}; 1276};
1238 1277
1239void 1278void
1240lpfc_get_cfgparam(struct lpfc_hba *phba) 1279lpfc_get_cfgparam(struct lpfc_hba *phba)
1241{ 1280{
1242 phba->cfg_log_verbose = lpfc_log_verbose; 1281 lpfc_log_verbose_init(phba, lpfc_log_verbose);
1243 phba->cfg_cr_delay = lpfc_cr_delay; 1282 lpfc_cr_delay_init(phba, lpfc_cr_delay);
1244 phba->cfg_cr_count = lpfc_cr_count; 1283 lpfc_cr_count_init(phba, lpfc_cr_count);
1245 phba->cfg_lun_queue_depth = lpfc_lun_queue_depth; 1284 lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
1246 phba->cfg_fcp_class = lpfc_fcp_class; 1285 lpfc_fcp_class_init(phba, lpfc_fcp_class);
1247 phba->cfg_use_adisc = lpfc_use_adisc; 1286 lpfc_use_adisc_init(phba, lpfc_use_adisc);
1248 phba->cfg_ack0 = lpfc_ack0; 1287 lpfc_ack0_init(phba, lpfc_ack0);
1249 phba->cfg_topology = lpfc_topology; 1288 lpfc_topology_init(phba, lpfc_topology);
1250 phba->cfg_scan_down = lpfc_scan_down; 1289 lpfc_scan_down_init(phba, lpfc_scan_down);
1251 phba->cfg_nodev_tmo = lpfc_nodev_tmo; 1290 lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
1252 phba->cfg_link_speed = lpfc_link_speed; 1291 lpfc_link_speed_init(phba, lpfc_link_speed);
1253 phba->cfg_fdmi_on = lpfc_fdmi_on; 1292 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
1254 phba->cfg_discovery_threads = lpfc_discovery_threads; 1293 lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
1255 phba->cfg_max_luns = lpfc_max_luns; 1294 lpfc_max_luns_init(phba, lpfc_max_luns);
1256 1295
1257 /* 1296 /*
1258 * The total number of segments is the configuration value plus 2 1297 * The total number of segments is the configuration value plus 2