aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_attr.c
diff options
context:
space:
mode:
authorJames.Smart@Emulex.Com <James.Smart@Emulex.Com>2005-10-28 20:29:13 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-10-29 11:12:49 -0400
commit7bcbb7527fb2f06b6500f6ee3e7f750a0ed0239c (patch)
treed9904852f6848d2c70df3843ee5829e71521946e /drivers/scsi/lpfc/lpfc_attr.c
parent755c0d06c58f7b84e9798365f806dadfef8c1839 (diff)
[SCSI] lpfc: Add range checking for attributes passed as options at load time.
Reuse macros defined for sysfs store callbacks in the initialization code in order to enforce the same range checking. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_attr.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c108
1 files changed, 64 insertions, 44 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 45c2ba7e94c2..fd5132d62ed2 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -286,45 +286,69 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \
286 struct Scsi_Host *host = class_to_shost(cdev);\ 286 struct Scsi_Host *host = class_to_shost(cdev);\
287 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ 287 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
288 int val = 0;\ 288 int val = 0;\
289 if (phba){\ 289 val = phba->cfg_##attr;\
290 val = phba->cfg_##attr;\ 290 return snprintf(buf, PAGE_SIZE, "%d\n",\
291 return snprintf(buf, PAGE_SIZE, "%d\n",\ 291 phba->cfg_##attr);\
292 phba->cfg_##attr);\ 292}
293
294#define lpfc_param_init(attr, default, minval, maxval) \
295static int \
296lpfc_##attr##_init(struct lpfc_hba *phba, int val) \
297{ \
298 if (val >= minval && val <= maxval) {\
299 phba->cfg_##attr = val;\
300 return 0;\
293 }\ 301 }\
294 return -EPERM;\ 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;\
295} 308}
296 309
297#define lpfc_param_store(attr, minval, maxval) \ 310#define lpfc_param_set(attr, default, minval, maxval) \
311static int \
312lpfc_##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) \
298static ssize_t \ 326static ssize_t \
299lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ 327lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
300{ \ 328{ \
301 struct Scsi_Host *host = class_to_shost(cdev);\ 329 struct Scsi_Host *host = class_to_shost(cdev);\
302 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\ 330 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
303 int val = 0;\ 331 int val=0;\
304 if (!isdigit(buf[0]))\ 332 if (sscanf(buf, "%d", &val) != 1)\
305 return -EINVAL;\ 333 return -EPERM;\
306 if (sscanf(buf, "0x%x", &val) != 1)\ 334 if (lpfc_##attr##_set(phba, val) == 0) \
307 if (sscanf(buf, "%d", &val) != 1)\
308 return -EINVAL;\
309 if (val >= minval && val <= maxval) {\
310 phba->cfg_##attr = val;\
311 return strlen(buf);\ 335 return strlen(buf);\
312 }\ 336 else \
313 return -EINVAL;\ 337 return -EINVAL;\
314} 338}
315 339
316#define LPFC_ATTR_R_NOINIT(name, desc) \ 340#define LPFC_ATTR(name, defval, minval, maxval, desc) \
317extern int lpfc_##name;\ 341static int lpfc_##name = defval;\
318module_param(lpfc_##name, int, 0);\ 342module_param(lpfc_##name, int, 0);\
319MODULE_PARM_DESC(lpfc_##name, desc);\ 343MODULE_PARM_DESC(lpfc_##name, desc);\
320lpfc_param_show(name)\ 344lpfc_param_init(name, defval, minval, maxval)
321static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
322 345
323#define LPFC_ATTR_R(name, defval, minval, maxval, desc) \ 346#define LPFC_ATTR_R(name, defval, minval, maxval, desc) \
324static int lpfc_##name = defval;\ 347static int lpfc_##name = defval;\
325module_param(lpfc_##name, int, 0);\ 348module_param(lpfc_##name, int, 0);\
326MODULE_PARM_DESC(lpfc_##name, desc);\ 349MODULE_PARM_DESC(lpfc_##name, desc);\
327lpfc_param_show(name)\ 350lpfc_param_show(name)\
351lpfc_param_init(name, defval, minval, maxval)\
328static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL) 352static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
329 353
330#define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \ 354#define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \
@@ -332,7 +356,9 @@ static int lpfc_##name = defval;\
332module_param(lpfc_##name, int, 0);\ 356module_param(lpfc_##name, int, 0);\
333MODULE_PARM_DESC(lpfc_##name, desc);\ 357MODULE_PARM_DESC(lpfc_##name, desc);\
334lpfc_param_show(name)\ 358lpfc_param_show(name)\
335lpfc_param_store(name, minval, maxval)\ 359lpfc_param_init(name, defval, minval, maxval)\
360lpfc_param_set(name, defval, minval, maxval)\
361lpfc_param_store(name)\
336static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\ 362static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
337 lpfc_##name##_show, lpfc_##name##_store) 363 lpfc_##name##_show, lpfc_##name##_store)
338 364
@@ -464,14 +490,10 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
464# is 0. Default value of cr_count is 1. The cr_count feature is disabled if 490# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
465# cr_delay is set to 0. 491# cr_delay is set to 0.
466*/ 492*/
467static int lpfc_cr_delay = 0; 493LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
468module_param(lpfc_cr_delay, int , 0);
469MODULE_PARM_DESC(lpfc_cr_delay, "A count of milliseconds after which an "
470 "interrupt response is generated"); 494 "interrupt response is generated");
471 495
472static int lpfc_cr_count = 1; 496LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"
473module_param(lpfc_cr_count, int, 0);
474MODULE_PARM_DESC(lpfc_cr_count, "A count of I/O completions after which an "
475 "interrupt response is generated"); 497 "interrupt response is generated");
476 498
477/* 499/*
@@ -487,9 +509,7 @@ LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
487# Specifies the maximum number of ELS cmds we can have outstanding (for 509# Specifies the maximum number of ELS cmds we can have outstanding (for
488# discovery). Value range is [1,64]. Default value = 32. 510# discovery). Value range is [1,64]. Default value = 32.
489*/ 511*/
490static int lpfc_discovery_threads = 32; 512LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands"
491module_param(lpfc_discovery_threads, int, 0);
492MODULE_PARM_DESC(lpfc_discovery_threads, "Maximum number of ELS commands "
493 "during discovery"); 513 "during discovery");
494 514
495/* 515/*
@@ -1225,20 +1245,20 @@ struct fc_function_template lpfc_transport_functions = {
1225void 1245void
1226lpfc_get_cfgparam(struct lpfc_hba *phba) 1246lpfc_get_cfgparam(struct lpfc_hba *phba)
1227{ 1247{
1228 phba->cfg_log_verbose = lpfc_log_verbose; 1248 lpfc_log_verbose_init(phba, lpfc_log_verbose);
1229 phba->cfg_cr_delay = lpfc_cr_delay; 1249 lpfc_cr_delay_init(phba, lpfc_cr_delay);
1230 phba->cfg_cr_count = lpfc_cr_count; 1250 lpfc_cr_count_init(phba, lpfc_cr_count);
1231 phba->cfg_lun_queue_depth = lpfc_lun_queue_depth; 1251 lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
1232 phba->cfg_fcp_class = lpfc_fcp_class; 1252 lpfc_fcp_class_init(phba, lpfc_fcp_class);
1233 phba->cfg_use_adisc = lpfc_use_adisc; 1253 lpfc_use_adisc_init(phba, lpfc_use_adisc);
1234 phba->cfg_ack0 = lpfc_ack0; 1254 lpfc_ack0_init(phba, lpfc_ack0);
1235 phba->cfg_topology = lpfc_topology; 1255 lpfc_topology_init(phba, lpfc_topology);
1236 phba->cfg_scan_down = lpfc_scan_down; 1256 lpfc_scan_down_init(phba, lpfc_scan_down);
1237 phba->cfg_nodev_tmo = lpfc_nodev_tmo; 1257 lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
1238 phba->cfg_link_speed = lpfc_link_speed; 1258 lpfc_link_speed_init(phba, lpfc_link_speed);
1239 phba->cfg_fdmi_on = lpfc_fdmi_on; 1259 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
1240 phba->cfg_discovery_threads = lpfc_discovery_threads; 1260 lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
1241 phba->cfg_max_luns = lpfc_max_luns; 1261 lpfc_max_luns_init(phba, lpfc_max_luns);
1242 1262
1243 /* 1263 /*
1244 * The total number of segments is the configuration value plus 2 1264 * The total number of segments is the configuration value plus 2