diff options
Diffstat (limited to 'drivers/scsi/bfa/bfad_attr.c')
-rw-r--r-- | drivers/scsi/bfa/bfad_attr.c | 649 |
1 files changed, 649 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c new file mode 100644 index 000000000000..9129ae3040ff --- /dev/null +++ b/drivers/scsi/bfa/bfad_attr.c | |||
@@ -0,0 +1,649 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | ||
3 | * All rights reserved | ||
4 | * www.brocade.com | ||
5 | * | ||
6 | * Linux driver for Brocade Fibre Channel Host Bus Adapter. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (GPL) Version 2 as | ||
10 | * published by the Free Software Foundation | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | /** | ||
19 | * bfa_attr.c Linux driver configuration interface module. | ||
20 | */ | ||
21 | |||
22 | #include "bfad_drv.h" | ||
23 | #include "bfad_im.h" | ||
24 | #include "bfad_trcmod.h" | ||
25 | #include "bfad_attr.h" | ||
26 | |||
27 | /** | ||
28 | * FC_transport_template FC transport template | ||
29 | */ | ||
30 | |||
31 | /** | ||
32 | * FC transport template entry, get SCSI target port ID. | ||
33 | */ | ||
34 | void | ||
35 | bfad_im_get_starget_port_id(struct scsi_target *starget) | ||
36 | { | ||
37 | struct Scsi_Host *shost; | ||
38 | struct bfad_im_port_s *im_port; | ||
39 | struct bfad_s *bfad; | ||
40 | struct bfad_itnim_s *itnim = NULL; | ||
41 | u32 fc_id = -1; | ||
42 | unsigned long flags; | ||
43 | |||
44 | shost = bfad_os_starget_to_shost(starget); | ||
45 | im_port = (struct bfad_im_port_s *) shost->hostdata[0]; | ||
46 | bfad = im_port->bfad; | ||
47 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
48 | |||
49 | itnim = bfad_os_get_itnim(im_port, starget->id); | ||
50 | if (itnim) | ||
51 | fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim); | ||
52 | |||
53 | fc_starget_port_id(starget) = fc_id; | ||
54 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * FC transport template entry, get SCSI target nwwn. | ||
59 | */ | ||
60 | void | ||
61 | bfad_im_get_starget_node_name(struct scsi_target *starget) | ||
62 | { | ||
63 | struct Scsi_Host *shost; | ||
64 | struct bfad_im_port_s *im_port; | ||
65 | struct bfad_s *bfad; | ||
66 | struct bfad_itnim_s *itnim = NULL; | ||
67 | u64 node_name = 0; | ||
68 | unsigned long flags; | ||
69 | |||
70 | shost = bfad_os_starget_to_shost(starget); | ||
71 | im_port = (struct bfad_im_port_s *) shost->hostdata[0]; | ||
72 | bfad = im_port->bfad; | ||
73 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
74 | |||
75 | itnim = bfad_os_get_itnim(im_port, starget->id); | ||
76 | if (itnim) | ||
77 | node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim); | ||
78 | |||
79 | fc_starget_node_name(starget) = bfa_os_htonll(node_name); | ||
80 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * FC transport template entry, get SCSI target pwwn. | ||
85 | */ | ||
86 | void | ||
87 | bfad_im_get_starget_port_name(struct scsi_target *starget) | ||
88 | { | ||
89 | struct Scsi_Host *shost; | ||
90 | struct bfad_im_port_s *im_port; | ||
91 | struct bfad_s *bfad; | ||
92 | struct bfad_itnim_s *itnim = NULL; | ||
93 | u64 port_name = 0; | ||
94 | unsigned long flags; | ||
95 | |||
96 | shost = bfad_os_starget_to_shost(starget); | ||
97 | im_port = (struct bfad_im_port_s *) shost->hostdata[0]; | ||
98 | bfad = im_port->bfad; | ||
99 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
100 | |||
101 | itnim = bfad_os_get_itnim(im_port, starget->id); | ||
102 | if (itnim) | ||
103 | port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim); | ||
104 | |||
105 | fc_starget_port_name(starget) = bfa_os_htonll(port_name); | ||
106 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * FC transport template entry, get SCSI host port ID. | ||
111 | */ | ||
112 | void | ||
113 | bfad_im_get_host_port_id(struct Scsi_Host *shost) | ||
114 | { | ||
115 | struct bfad_im_port_s *im_port = | ||
116 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
117 | struct bfad_port_s *port = im_port->port; | ||
118 | |||
119 | fc_host_port_id(shost) = | ||
120 | bfa_os_hton3b(bfa_fcs_port_get_fcid(port->fcs_port)); | ||
121 | } | ||
122 | |||
123 | |||
124 | |||
125 | |||
126 | |||
127 | struct Scsi_Host * | ||
128 | bfad_os_starget_to_shost(struct scsi_target *starget) | ||
129 | { | ||
130 | return dev_to_shost(starget->dev.parent); | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * FC transport template entry, get SCSI host port type. | ||
135 | */ | ||
136 | static void | ||
137 | bfad_im_get_host_port_type(struct Scsi_Host *shost) | ||
138 | { | ||
139 | struct bfad_im_port_s *im_port = | ||
140 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
141 | struct bfad_s *bfad = im_port->bfad; | ||
142 | struct bfa_pport_attr_s attr; | ||
143 | |||
144 | bfa_pport_get_attr(&bfad->bfa, &attr); | ||
145 | |||
146 | switch (attr.port_type) { | ||
147 | case BFA_PPORT_TYPE_NPORT: | ||
148 | fc_host_port_type(shost) = FC_PORTTYPE_NPORT; | ||
149 | break; | ||
150 | case BFA_PPORT_TYPE_NLPORT: | ||
151 | fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; | ||
152 | break; | ||
153 | case BFA_PPORT_TYPE_P2P: | ||
154 | fc_host_port_type(shost) = FC_PORTTYPE_PTP; | ||
155 | break; | ||
156 | case BFA_PPORT_TYPE_LPORT: | ||
157 | fc_host_port_type(shost) = FC_PORTTYPE_LPORT; | ||
158 | break; | ||
159 | default: | ||
160 | fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; | ||
161 | break; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * FC transport template entry, get SCSI host port state. | ||
167 | */ | ||
168 | static void | ||
169 | bfad_im_get_host_port_state(struct Scsi_Host *shost) | ||
170 | { | ||
171 | struct bfad_im_port_s *im_port = | ||
172 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
173 | struct bfad_s *bfad = im_port->bfad; | ||
174 | struct bfa_pport_attr_s attr; | ||
175 | |||
176 | bfa_pport_get_attr(&bfad->bfa, &attr); | ||
177 | |||
178 | switch (attr.port_state) { | ||
179 | case BFA_PPORT_ST_LINKDOWN: | ||
180 | fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; | ||
181 | break; | ||
182 | case BFA_PPORT_ST_LINKUP: | ||
183 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; | ||
184 | break; | ||
185 | case BFA_PPORT_ST_UNINIT: | ||
186 | case BFA_PPORT_ST_ENABLING_QWAIT: | ||
187 | case BFA_PPORT_ST_ENABLING: | ||
188 | case BFA_PPORT_ST_DISABLING_QWAIT: | ||
189 | case BFA_PPORT_ST_DISABLING: | ||
190 | case BFA_PPORT_ST_DISABLED: | ||
191 | case BFA_PPORT_ST_STOPPED: | ||
192 | case BFA_PPORT_ST_IOCDOWN: | ||
193 | default: | ||
194 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | ||
195 | break; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * FC transport template entry, get SCSI host active fc4s. | ||
201 | */ | ||
202 | static void | ||
203 | bfad_im_get_host_active_fc4s(struct Scsi_Host *shost) | ||
204 | { | ||
205 | struct bfad_im_port_s *im_port = | ||
206 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
207 | struct bfad_port_s *port = im_port->port; | ||
208 | |||
209 | memset(fc_host_active_fc4s(shost), 0, | ||
210 | sizeof(fc_host_active_fc4s(shost))); | ||
211 | |||
212 | if (port->supported_fc4s & | ||
213 | (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM)) | ||
214 | fc_host_active_fc4s(shost)[2] = 1; | ||
215 | |||
216 | if (port->supported_fc4s & BFA_PORT_ROLE_FCP_IPFC) | ||
217 | fc_host_active_fc4s(shost)[3] = 0x20; | ||
218 | |||
219 | fc_host_active_fc4s(shost)[7] = 1; | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * FC transport template entry, get SCSI host link speed. | ||
224 | */ | ||
225 | static void | ||
226 | bfad_im_get_host_speed(struct Scsi_Host *shost) | ||
227 | { | ||
228 | struct bfad_im_port_s *im_port = | ||
229 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
230 | struct bfad_s *bfad = im_port->bfad; | ||
231 | struct bfa_pport_attr_s attr; | ||
232 | |||
233 | bfa_pport_get_attr(&bfad->bfa, &attr); | ||
234 | switch (attr.speed) { | ||
235 | case BFA_PPORT_SPEED_8GBPS: | ||
236 | fc_host_speed(shost) = FC_PORTSPEED_8GBIT; | ||
237 | break; | ||
238 | case BFA_PPORT_SPEED_4GBPS: | ||
239 | fc_host_speed(shost) = FC_PORTSPEED_4GBIT; | ||
240 | break; | ||
241 | case BFA_PPORT_SPEED_2GBPS: | ||
242 | fc_host_speed(shost) = FC_PORTSPEED_2GBIT; | ||
243 | break; | ||
244 | case BFA_PPORT_SPEED_1GBPS: | ||
245 | fc_host_speed(shost) = FC_PORTSPEED_1GBIT; | ||
246 | break; | ||
247 | default: | ||
248 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | ||
249 | break; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * FC transport template entry, get SCSI host port type. | ||
255 | */ | ||
256 | static void | ||
257 | bfad_im_get_host_fabric_name(struct Scsi_Host *shost) | ||
258 | { | ||
259 | struct bfad_im_port_s *im_port = | ||
260 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
261 | struct bfad_port_s *port = im_port->port; | ||
262 | wwn_t fabric_nwwn = 0; | ||
263 | |||
264 | fabric_nwwn = bfa_fcs_port_get_fabric_name(port->fcs_port); | ||
265 | |||
266 | fc_host_fabric_name(shost) = bfa_os_htonll(fabric_nwwn); | ||
267 | |||
268 | } | ||
269 | |||
270 | /** | ||
271 | * FC transport template entry, get BFAD statistics. | ||
272 | */ | ||
273 | static struct fc_host_statistics * | ||
274 | bfad_im_get_stats(struct Scsi_Host *shost) | ||
275 | { | ||
276 | struct bfad_im_port_s *im_port = | ||
277 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
278 | struct bfad_s *bfad = im_port->bfad; | ||
279 | struct bfad_hal_comp fcomp; | ||
280 | struct fc_host_statistics *hstats; | ||
281 | bfa_status_t rc; | ||
282 | unsigned long flags; | ||
283 | |||
284 | hstats = &bfad->link_stats; | ||
285 | init_completion(&fcomp.comp); | ||
286 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
287 | memset(hstats, 0, sizeof(struct fc_host_statistics)); | ||
288 | rc = bfa_pport_get_stats(&bfad->bfa, | ||
289 | (union bfa_pport_stats_u *) hstats, | ||
290 | bfad_hcb_comp, &fcomp); | ||
291 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
292 | if (rc != BFA_STATUS_OK) | ||
293 | return NULL; | ||
294 | |||
295 | wait_for_completion(&fcomp.comp); | ||
296 | |||
297 | return hstats; | ||
298 | } | ||
299 | |||
300 | /** | ||
301 | * FC transport template entry, reset BFAD statistics. | ||
302 | */ | ||
303 | static void | ||
304 | bfad_im_reset_stats(struct Scsi_Host *shost) | ||
305 | { | ||
306 | struct bfad_im_port_s *im_port = | ||
307 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
308 | struct bfad_s *bfad = im_port->bfad; | ||
309 | struct bfad_hal_comp fcomp; | ||
310 | unsigned long flags; | ||
311 | bfa_status_t rc; | ||
312 | |||
313 | init_completion(&fcomp.comp); | ||
314 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
315 | rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp); | ||
316 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
317 | |||
318 | if (rc != BFA_STATUS_OK) | ||
319 | return; | ||
320 | |||
321 | wait_for_completion(&fcomp.comp); | ||
322 | |||
323 | return; | ||
324 | } | ||
325 | |||
326 | /** | ||
327 | * FC transport template entry, get rport loss timeout. | ||
328 | */ | ||
329 | static void | ||
330 | bfad_im_get_rport_loss_tmo(struct fc_rport *rport) | ||
331 | { | ||
332 | struct bfad_itnim_data_s *itnim_data = rport->dd_data; | ||
333 | struct bfad_itnim_s *itnim = itnim_data->itnim; | ||
334 | struct bfad_s *bfad = itnim->im->bfad; | ||
335 | unsigned long flags; | ||
336 | |||
337 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
338 | rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); | ||
339 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * FC transport template entry, set rport loss timeout. | ||
344 | */ | ||
345 | static void | ||
346 | bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) | ||
347 | { | ||
348 | struct bfad_itnim_data_s *itnim_data = rport->dd_data; | ||
349 | struct bfad_itnim_s *itnim = itnim_data->itnim; | ||
350 | struct bfad_s *bfad = itnim->im->bfad; | ||
351 | unsigned long flags; | ||
352 | |||
353 | if (timeout > 0) { | ||
354 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
355 | bfa_fcpim_path_tov_set(&bfad->bfa, timeout); | ||
356 | rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); | ||
357 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
358 | } | ||
359 | |||
360 | } | ||
361 | |||
362 | struct fc_function_template bfad_im_fc_function_template = { | ||
363 | |||
364 | /* Target dynamic attributes */ | ||
365 | .get_starget_port_id = bfad_im_get_starget_port_id, | ||
366 | .show_starget_port_id = 1, | ||
367 | .get_starget_node_name = bfad_im_get_starget_node_name, | ||
368 | .show_starget_node_name = 1, | ||
369 | .get_starget_port_name = bfad_im_get_starget_port_name, | ||
370 | .show_starget_port_name = 1, | ||
371 | |||
372 | /* Host dynamic attribute */ | ||
373 | .get_host_port_id = bfad_im_get_host_port_id, | ||
374 | .show_host_port_id = 1, | ||
375 | |||
376 | /* Host fixed attributes */ | ||
377 | .show_host_node_name = 1, | ||
378 | .show_host_port_name = 1, | ||
379 | .show_host_supported_classes = 1, | ||
380 | .show_host_supported_fc4s = 1, | ||
381 | .show_host_supported_speeds = 1, | ||
382 | .show_host_maxframe_size = 1, | ||
383 | |||
384 | /* More host dynamic attributes */ | ||
385 | .show_host_port_type = 1, | ||
386 | .get_host_port_type = bfad_im_get_host_port_type, | ||
387 | .show_host_port_state = 1, | ||
388 | .get_host_port_state = bfad_im_get_host_port_state, | ||
389 | .show_host_active_fc4s = 1, | ||
390 | .get_host_active_fc4s = bfad_im_get_host_active_fc4s, | ||
391 | .show_host_speed = 1, | ||
392 | .get_host_speed = bfad_im_get_host_speed, | ||
393 | .show_host_fabric_name = 1, | ||
394 | .get_host_fabric_name = bfad_im_get_host_fabric_name, | ||
395 | |||
396 | .show_host_symbolic_name = 1, | ||
397 | |||
398 | /* Statistics */ | ||
399 | .get_fc_host_stats = bfad_im_get_stats, | ||
400 | .reset_fc_host_stats = bfad_im_reset_stats, | ||
401 | |||
402 | /* Allocation length for host specific data */ | ||
403 | .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), | ||
404 | |||
405 | /* Remote port fixed attributes */ | ||
406 | .show_rport_maxframe_size = 1, | ||
407 | .show_rport_supported_classes = 1, | ||
408 | .show_rport_dev_loss_tmo = 1, | ||
409 | .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, | ||
410 | .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, | ||
411 | }; | ||
412 | |||
413 | /** | ||
414 | * Scsi_Host_attrs SCSI host attributes | ||
415 | */ | ||
416 | static ssize_t | ||
417 | bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr, | ||
418 | char *buf) | ||
419 | { | ||
420 | struct Scsi_Host *shost = class_to_shost(dev); | ||
421 | struct bfad_im_port_s *im_port = | ||
422 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
423 | struct bfad_s *bfad = im_port->bfad; | ||
424 | struct bfa_ioc_attr_s ioc_attr; | ||
425 | |||
426 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
427 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
428 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
429 | ioc_attr.adapter_attr.serial_num); | ||
430 | } | ||
431 | |||
432 | static ssize_t | ||
433 | bfad_im_model_show(struct device *dev, struct device_attribute *attr, | ||
434 | char *buf) | ||
435 | { | ||
436 | struct Scsi_Host *shost = class_to_shost(dev); | ||
437 | struct bfad_im_port_s *im_port = | ||
438 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
439 | struct bfad_s *bfad = im_port->bfad; | ||
440 | struct bfa_ioc_attr_s ioc_attr; | ||
441 | |||
442 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
443 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
444 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model); | ||
445 | } | ||
446 | |||
447 | static ssize_t | ||
448 | bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, | ||
449 | char *buf) | ||
450 | { | ||
451 | struct Scsi_Host *shost = class_to_shost(dev); | ||
452 | struct bfad_im_port_s *im_port = | ||
453 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
454 | struct bfad_s *bfad = im_port->bfad; | ||
455 | struct bfa_ioc_attr_s ioc_attr; | ||
456 | |||
457 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
458 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
459 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
460 | ioc_attr.adapter_attr.model_descr); | ||
461 | } | ||
462 | |||
463 | static ssize_t | ||
464 | bfad_im_node_name_show(struct device *dev, struct device_attribute *attr, | ||
465 | char *buf) | ||
466 | { | ||
467 | struct Scsi_Host *shost = class_to_shost(dev); | ||
468 | struct bfad_im_port_s *im_port = | ||
469 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
470 | struct bfad_port_s *port = im_port->port; | ||
471 | u64 nwwn; | ||
472 | |||
473 | nwwn = bfa_fcs_port_get_nwwn(port->fcs_port); | ||
474 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", bfa_os_htonll(nwwn)); | ||
475 | } | ||
476 | |||
477 | static ssize_t | ||
478 | bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, | ||
479 | char *buf) | ||
480 | { | ||
481 | struct Scsi_Host *shost = class_to_shost(dev); | ||
482 | struct bfad_im_port_s *im_port = | ||
483 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
484 | struct bfad_s *bfad = im_port->bfad; | ||
485 | struct bfa_ioc_attr_s ioc_attr; | ||
486 | |||
487 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
488 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
489 | |||
490 | return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n", | ||
491 | ioc_attr.adapter_attr.model, | ||
492 | ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION); | ||
493 | } | ||
494 | |||
495 | static ssize_t | ||
496 | bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, | ||
497 | char *buf) | ||
498 | { | ||
499 | struct Scsi_Host *shost = class_to_shost(dev); | ||
500 | struct bfad_im_port_s *im_port = | ||
501 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
502 | struct bfad_s *bfad = im_port->bfad; | ||
503 | struct bfa_ioc_attr_s ioc_attr; | ||
504 | |||
505 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
506 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
507 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver); | ||
508 | } | ||
509 | |||
510 | static ssize_t | ||
511 | bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, | ||
512 | char *buf) | ||
513 | { | ||
514 | return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION); | ||
515 | } | ||
516 | |||
517 | static ssize_t | ||
518 | bfad_im_optionrom_version_show(struct device *dev, | ||
519 | struct device_attribute *attr, char *buf) | ||
520 | { | ||
521 | struct Scsi_Host *shost = class_to_shost(dev); | ||
522 | struct bfad_im_port_s *im_port = | ||
523 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
524 | struct bfad_s *bfad = im_port->bfad; | ||
525 | struct bfa_ioc_attr_s ioc_attr; | ||
526 | |||
527 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
528 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
529 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
530 | ioc_attr.adapter_attr.optrom_ver); | ||
531 | } | ||
532 | |||
533 | static ssize_t | ||
534 | bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr, | ||
535 | char *buf) | ||
536 | { | ||
537 | struct Scsi_Host *shost = class_to_shost(dev); | ||
538 | struct bfad_im_port_s *im_port = | ||
539 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
540 | struct bfad_s *bfad = im_port->bfad; | ||
541 | struct bfa_ioc_attr_s ioc_attr; | ||
542 | |||
543 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
544 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
545 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver); | ||
546 | } | ||
547 | |||
548 | static ssize_t | ||
549 | bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, | ||
550 | char *buf) | ||
551 | { | ||
552 | struct Scsi_Host *shost = class_to_shost(dev); | ||
553 | struct bfad_im_port_s *im_port = | ||
554 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
555 | struct bfad_s *bfad = im_port->bfad; | ||
556 | struct bfa_ioc_attr_s ioc_attr; | ||
557 | |||
558 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
559 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
560 | return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports); | ||
561 | } | ||
562 | |||
563 | static ssize_t | ||
564 | bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, | ||
565 | char *buf) | ||
566 | { | ||
567 | return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME); | ||
568 | } | ||
569 | |||
570 | static ssize_t | ||
571 | bfad_im_num_of_discovered_ports_show(struct device *dev, | ||
572 | struct device_attribute *attr, char *buf) | ||
573 | { | ||
574 | struct Scsi_Host *shost = class_to_shost(dev); | ||
575 | struct bfad_im_port_s *im_port = | ||
576 | (struct bfad_im_port_s *) shost->hostdata[0]; | ||
577 | struct bfad_port_s *port = im_port->port; | ||
578 | struct bfad_s *bfad = im_port->bfad; | ||
579 | int nrports = 2048; | ||
580 | wwn_t *rports = NULL; | ||
581 | unsigned long flags; | ||
582 | |||
583 | rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC); | ||
584 | if (rports == NULL) | ||
585 | return -ENOMEM; | ||
586 | |||
587 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
588 | bfa_fcs_port_get_rports(port->fcs_port, rports, &nrports); | ||
589 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
590 | kfree(rports); | ||
591 | |||
592 | return snprintf(buf, PAGE_SIZE, "%d\n", nrports); | ||
593 | } | ||
594 | |||
595 | static DEVICE_ATTR(serial_number, S_IRUGO, | ||
596 | bfad_im_serial_num_show, NULL); | ||
597 | static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL); | ||
598 | static DEVICE_ATTR(model_description, S_IRUGO, | ||
599 | bfad_im_model_desc_show, NULL); | ||
600 | static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL); | ||
601 | static DEVICE_ATTR(symbolic_name, S_IRUGO, | ||
602 | bfad_im_symbolic_name_show, NULL); | ||
603 | static DEVICE_ATTR(hardware_version, S_IRUGO, | ||
604 | bfad_im_hw_version_show, NULL); | ||
605 | static DEVICE_ATTR(driver_version, S_IRUGO, | ||
606 | bfad_im_drv_version_show, NULL); | ||
607 | static DEVICE_ATTR(option_rom_version, S_IRUGO, | ||
608 | bfad_im_optionrom_version_show, NULL); | ||
609 | static DEVICE_ATTR(firmware_version, S_IRUGO, | ||
610 | bfad_im_fw_version_show, NULL); | ||
611 | static DEVICE_ATTR(number_of_ports, S_IRUGO, | ||
612 | bfad_im_num_of_ports_show, NULL); | ||
613 | static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL); | ||
614 | static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO, | ||
615 | bfad_im_num_of_discovered_ports_show, NULL); | ||
616 | |||
617 | struct device_attribute *bfad_im_host_attrs[] = { | ||
618 | &dev_attr_serial_number, | ||
619 | &dev_attr_model, | ||
620 | &dev_attr_model_description, | ||
621 | &dev_attr_node_name, | ||
622 | &dev_attr_symbolic_name, | ||
623 | &dev_attr_hardware_version, | ||
624 | &dev_attr_driver_version, | ||
625 | &dev_attr_option_rom_version, | ||
626 | &dev_attr_firmware_version, | ||
627 | &dev_attr_number_of_ports, | ||
628 | &dev_attr_driver_name, | ||
629 | &dev_attr_number_of_discovered_ports, | ||
630 | NULL, | ||
631 | }; | ||
632 | |||
633 | struct device_attribute *bfad_im_vport_attrs[] = { | ||
634 | &dev_attr_serial_number, | ||
635 | &dev_attr_model, | ||
636 | &dev_attr_model_description, | ||
637 | &dev_attr_node_name, | ||
638 | &dev_attr_symbolic_name, | ||
639 | &dev_attr_hardware_version, | ||
640 | &dev_attr_driver_version, | ||
641 | &dev_attr_option_rom_version, | ||
642 | &dev_attr_firmware_version, | ||
643 | &dev_attr_number_of_ports, | ||
644 | &dev_attr_driver_name, | ||
645 | &dev_attr_number_of_discovered_ports, | ||
646 | NULL, | ||
647 | }; | ||
648 | |||
649 | |||