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.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 89e8222bc7cc..5625a8c2a8fd 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -278,6 +278,71 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
278 return -EIO; 278 return -EIO;
279} 279}
280 280
281static ssize_t
282lpfc_poll_show(struct class_device *cdev, char *buf)
283{
284 struct Scsi_Host *host = class_to_shost(cdev);
285 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
286
287 return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
288}
289
290static ssize_t
291lpfc_poll_store(struct class_device *cdev, const char *buf,
292 size_t count)
293{
294 struct Scsi_Host *host = class_to_shost(cdev);
295 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
296 uint32_t creg_val;
297 uint32_t old_val;
298 int val=0;
299
300 if (!isdigit(buf[0]))
301 return -EINVAL;
302
303 if (sscanf(buf, "%i", &val) != 1)
304 return -EINVAL;
305
306 if ((val & 0x3) != val)
307 return -EINVAL;
308
309 spin_lock_irq(phba->host->host_lock);
310
311 old_val = phba->cfg_poll;
312
313 if (val & ENABLE_FCP_RING_POLLING) {
314 if ((val & DISABLE_FCP_RING_INT) &&
315 !(old_val & DISABLE_FCP_RING_INT)) {
316 creg_val = readl(phba->HCregaddr);
317 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
318 writel(creg_val, phba->HCregaddr);
319 readl(phba->HCregaddr); /* flush */
320
321 lpfc_poll_start_timer(phba);
322 }
323 } else if (val != 0x0) {
324 spin_unlock_irq(phba->host->host_lock);
325 return -EINVAL;
326 }
327
328 if (!(val & DISABLE_FCP_RING_INT) &&
329 (old_val & DISABLE_FCP_RING_INT))
330 {
331 spin_unlock_irq(phba->host->host_lock);
332 del_timer(&phba->fcp_poll_timer);
333 spin_lock_irq(phba->host->host_lock);
334 creg_val = readl(phba->HCregaddr);
335 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
336 writel(creg_val, phba->HCregaddr);
337 readl(phba->HCregaddr); /* flush */
338 }
339
340 phba->cfg_poll = val;
341
342 spin_unlock_irq(phba->host->host_lock);
343
344 return strlen(buf);
345}
281 346
282#define lpfc_param_show(attr) \ 347#define lpfc_param_show(attr) \
283static ssize_t \ 348static ssize_t \
@@ -416,6 +481,15 @@ static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
416static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, 481static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
417 lpfc_board_online_show, lpfc_board_online_store); 482 lpfc_board_online_show, lpfc_board_online_store);
418 483
484static int lpfc_poll = 0;
485module_param(lpfc_poll, int, 0);
486MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
487 " 0 - none,"
488 " 1 - poll with interrupts enabled"
489 " 3 - poll and disable FCP ring interrupts");
490
491static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,
492 lpfc_poll_show, lpfc_poll_store);
419 493
420/* 494/*
421# lpfc_log_verbose: Only turn this flag on if you are willing to risk being 495# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
@@ -523,10 +597,10 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
523# is 0. Default value of cr_count is 1. The cr_count feature is disabled if 597# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
524# cr_delay is set to 0. 598# cr_delay is set to 0.
525*/ 599*/
526LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an" 600LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
527 "interrupt response is generated"); 601 "interrupt response is generated");
528 602
529LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an" 603LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an"
530 "interrupt response is generated"); 604 "interrupt response is generated");
531 605
532/* 606/*
@@ -553,6 +627,13 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands"
553LPFC_ATTR_R(max_luns, 256, 1, 32768, 627LPFC_ATTR_R(max_luns, 256, 1, 32768,
554 "Maximum number of LUNs per target driver will support"); 628 "Maximum number of LUNs per target driver will support");
555 629
630/*
631# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
632# Value range is [1,255], default value is 10.
633*/
634LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
635 "Milliseconds driver will wait between polling FCP ring");
636
556struct class_device_attribute *lpfc_host_attrs[] = { 637struct class_device_attribute *lpfc_host_attrs[] = {
557 &class_device_attr_info, 638 &class_device_attr_info,
558 &class_device_attr_serialnum, 639 &class_device_attr_serialnum,
@@ -575,11 +656,15 @@ struct class_device_attribute *lpfc_host_attrs[] = {
575 &class_device_attr_lpfc_topology, 656 &class_device_attr_lpfc_topology,
576 &class_device_attr_lpfc_scan_down, 657 &class_device_attr_lpfc_scan_down,
577 &class_device_attr_lpfc_link_speed, 658 &class_device_attr_lpfc_link_speed,
659 &class_device_attr_lpfc_cr_delay,
660 &class_device_attr_lpfc_cr_count,
578 &class_device_attr_lpfc_fdmi_on, 661 &class_device_attr_lpfc_fdmi_on,
579 &class_device_attr_lpfc_max_luns, 662 &class_device_attr_lpfc_max_luns,
580 &class_device_attr_nport_evt_cnt, 663 &class_device_attr_nport_evt_cnt,
581 &class_device_attr_management_version, 664 &class_device_attr_management_version,
582 &class_device_attr_board_online, 665 &class_device_attr_board_online,
666 &class_device_attr_lpfc_poll,
667 &class_device_attr_lpfc_poll_tmo,
583 NULL, 668 NULL,
584}; 669};
585 670
@@ -1292,6 +1377,9 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
1292 lpfc_fdmi_on_init(phba, lpfc_fdmi_on); 1377 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
1293 lpfc_discovery_threads_init(phba, lpfc_discovery_threads); 1378 lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
1294 lpfc_max_luns_init(phba, lpfc_max_luns); 1379 lpfc_max_luns_init(phba, lpfc_max_luns);
1380 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
1381
1382 phba->cfg_poll = lpfc_poll;
1295 1383
1296 /* 1384 /*
1297 * The total number of segments is the configuration value plus 2 1385 * The total number of segments is the configuration value plus 2