1 | /* bnx2i_sysfs.c: QLogic NetXtreme II iSCSI driver. |
2 | * |
3 | * Copyright (c) 2004 - 2013 Broadcom Corporation |
4 | * Copyright (c) 2014, QLogic Corporation |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation. |
9 | * |
10 | * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) |
11 | * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com) |
12 | * Maintained by: QLogic-Storage-Upstream@qlogic.com |
13 | */ |
14 | |
15 | #include "bnx2i.h" |
16 | |
17 | /** |
18 | * bnx2i_dev_to_hba - maps dev pointer to adapter struct |
19 | * @dev: device pointer |
20 | * |
21 | * Map device to hba structure |
22 | */ |
23 | static inline struct bnx2i_hba *bnx2i_dev_to_hba(struct device *dev) |
24 | { |
25 | struct Scsi_Host *shost = class_to_shost(dev); |
26 | return iscsi_host_priv(shost); |
27 | } |
28 | |
29 | |
30 | /** |
31 | * bnx2i_show_sq_info - return(s currently configured send queue (SQ) size |
32 | * @dev: device pointer |
33 | * @attr: device attribute (unused) |
34 | * @buf: buffer to return current SQ size parameter |
35 | * |
36 | * Returns current SQ size parameter, this paramater determines the number |
37 | * outstanding iSCSI commands supported on a connection |
38 | */ |
39 | static ssize_t bnx2i_show_sq_info(struct device *dev, |
40 | struct device_attribute *attr, char *buf) |
41 | { |
42 | struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev); |
43 | |
44 | return sprintf(buf, fmt: "0x%x\n" , hba->max_sqes); |
45 | } |
46 | |
47 | |
48 | /** |
49 | * bnx2i_set_sq_info - update send queue (SQ) size parameter |
50 | * @dev: device pointer |
51 | * @attr: device attribute (unused) |
52 | * @buf: buffer to return current SQ size parameter |
53 | * @count: parameter buffer size |
54 | * |
55 | * Interface for user to change shared queue size allocated for each conn |
56 | * Must be within SQ limits and a power of 2. For the latter this is needed |
57 | * because of how libiscsi preallocates tasks. |
58 | */ |
59 | static ssize_t bnx2i_set_sq_info(struct device *dev, |
60 | struct device_attribute *attr, |
61 | const char *buf, size_t count) |
62 | { |
63 | struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev); |
64 | u32 val; |
65 | int max_sq_size; |
66 | |
67 | if (hba->ofld_conns_active) |
68 | goto skip_config; |
69 | |
70 | if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) |
71 | max_sq_size = BNX2I_5770X_SQ_WQES_MAX; |
72 | else |
73 | max_sq_size = BNX2I_570X_SQ_WQES_MAX; |
74 | |
75 | if (sscanf(buf, " 0x%x " , &val) > 0) { |
76 | if ((val >= BNX2I_SQ_WQES_MIN) && (val <= max_sq_size) && |
77 | (is_power_of_2(n: val))) |
78 | hba->max_sqes = val; |
79 | } |
80 | |
81 | return count; |
82 | |
83 | skip_config: |
84 | printk(KERN_ERR "bnx2i: device busy, cannot change SQ size\n" ); |
85 | return 0; |
86 | } |
87 | |
88 | |
89 | /** |
90 | * bnx2i_show_ccell_info - returns command cell (HQ) size |
91 | * @dev: device pointer |
92 | * @attr: device attribute (unused) |
93 | * @buf: buffer to return current SQ size parameter |
94 | * |
95 | * returns per-connection TCP history queue size parameter |
96 | */ |
97 | static ssize_t bnx2i_show_ccell_info(struct device *dev, |
98 | struct device_attribute *attr, char *buf) |
99 | { |
100 | struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev); |
101 | |
102 | return sprintf(buf, fmt: "0x%x\n" , hba->num_ccell); |
103 | } |
104 | |
105 | |
106 | /** |
107 | * bnx2i_set_ccell_info - set command cell (HQ) size |
108 | * @dev: device pointer |
109 | * @attr: device attribute (unused) |
110 | * @buf: buffer to return current SQ size parameter |
111 | * @count: parameter buffer size |
112 | * |
113 | * updates per-connection TCP history queue size parameter |
114 | */ |
115 | static ssize_t bnx2i_set_ccell_info(struct device *dev, |
116 | struct device_attribute *attr, |
117 | const char *buf, size_t count) |
118 | { |
119 | u32 val; |
120 | struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev); |
121 | |
122 | if (hba->ofld_conns_active) |
123 | goto skip_config; |
124 | |
125 | if (sscanf(buf, " 0x%x " , &val) > 0) { |
126 | if ((val >= BNX2I_CCELLS_MIN) && |
127 | (val <= BNX2I_CCELLS_MAX)) { |
128 | hba->num_ccell = val; |
129 | } |
130 | } |
131 | |
132 | return count; |
133 | |
134 | skip_config: |
135 | printk(KERN_ERR "bnx2i: device busy, cannot change CCELL size\n" ); |
136 | return 0; |
137 | } |
138 | |
139 | |
140 | static DEVICE_ATTR(sq_size, S_IRUGO | S_IWUSR, |
141 | bnx2i_show_sq_info, bnx2i_set_sq_info); |
142 | static DEVICE_ATTR(num_ccell, S_IRUGO | S_IWUSR, |
143 | bnx2i_show_ccell_info, bnx2i_set_ccell_info); |
144 | |
145 | static struct attribute *bnx2i_dev_attributes[] = { |
146 | &dev_attr_sq_size.attr, |
147 | &dev_attr_num_ccell.attr, |
148 | NULL |
149 | }; |
150 | |
151 | static const struct attribute_group bnx2i_dev_attr_group = { |
152 | .attrs = bnx2i_dev_attributes |
153 | }; |
154 | |
155 | const struct attribute_group *bnx2i_dev_groups[] = { |
156 | &bnx2i_dev_attr_group, |
157 | NULL |
158 | }; |
159 | |