Commit | Line | Data |
---|---|---|
7725ccfd | 1 | /* |
a36c61f9 | 2 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. |
7725ccfd JH |
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 | ||
5fbe25c7 | 18 | /* |
7725ccfd JH |
19 | * bfa_attr.c Linux driver configuration interface module. |
20 | */ | |
21 | ||
22 | #include "bfad_drv.h" | |
23 | #include "bfad_im.h" | |
7725ccfd | 24 | |
5fbe25c7 | 25 | /* |
7725ccfd JH |
26 | * FC transport template entry, get SCSI target port ID. |
27 | */ | |
52f94b6f | 28 | static void |
7725ccfd JH |
29 | bfad_im_get_starget_port_id(struct scsi_target *starget) |
30 | { | |
31 | struct Scsi_Host *shost; | |
32 | struct bfad_im_port_s *im_port; | |
33 | struct bfad_s *bfad; | |
34 | struct bfad_itnim_s *itnim = NULL; | |
35 | u32 fc_id = -1; | |
36 | unsigned long flags; | |
37 | ||
a36c61f9 | 38 | shost = dev_to_shost(starget->dev.parent); |
7725ccfd JH |
39 | im_port = (struct bfad_im_port_s *) shost->hostdata[0]; |
40 | bfad = im_port->bfad; | |
41 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
42 | ||
f16a1750 | 43 | itnim = bfad_get_itnim(im_port, starget->id); |
7725ccfd JH |
44 | if (itnim) |
45 | fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim); | |
46 | ||
47 | fc_starget_port_id(starget) = fc_id; | |
48 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
49 | } | |
50 | ||
5fbe25c7 | 51 | /* |
7725ccfd JH |
52 | * FC transport template entry, get SCSI target nwwn. |
53 | */ | |
52f94b6f | 54 | static void |
7725ccfd JH |
55 | bfad_im_get_starget_node_name(struct scsi_target *starget) |
56 | { | |
57 | struct Scsi_Host *shost; | |
58 | struct bfad_im_port_s *im_port; | |
59 | struct bfad_s *bfad; | |
60 | struct bfad_itnim_s *itnim = NULL; | |
61 | u64 node_name = 0; | |
62 | unsigned long flags; | |
63 | ||
a36c61f9 | 64 | shost = dev_to_shost(starget->dev.parent); |
7725ccfd JH |
65 | im_port = (struct bfad_im_port_s *) shost->hostdata[0]; |
66 | bfad = im_port->bfad; | |
67 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
68 | ||
f16a1750 | 69 | itnim = bfad_get_itnim(im_port, starget->id); |
7725ccfd JH |
70 | if (itnim) |
71 | node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim); | |
72 | ||
ba816ea8 | 73 | fc_starget_node_name(starget) = cpu_to_be64(node_name); |
7725ccfd JH |
74 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
75 | } | |
76 | ||
5fbe25c7 | 77 | /* |
7725ccfd JH |
78 | * FC transport template entry, get SCSI target pwwn. |
79 | */ | |
52f94b6f | 80 | static void |
7725ccfd JH |
81 | bfad_im_get_starget_port_name(struct scsi_target *starget) |
82 | { | |
83 | struct Scsi_Host *shost; | |
84 | struct bfad_im_port_s *im_port; | |
85 | struct bfad_s *bfad; | |
86 | struct bfad_itnim_s *itnim = NULL; | |
87 | u64 port_name = 0; | |
88 | unsigned long flags; | |
89 | ||
a36c61f9 | 90 | shost = dev_to_shost(starget->dev.parent); |
7725ccfd JH |
91 | im_port = (struct bfad_im_port_s *) shost->hostdata[0]; |
92 | bfad = im_port->bfad; | |
93 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
94 | ||
f16a1750 | 95 | itnim = bfad_get_itnim(im_port, starget->id); |
7725ccfd JH |
96 | if (itnim) |
97 | port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim); | |
98 | ||
ba816ea8 | 99 | fc_starget_port_name(starget) = cpu_to_be64(port_name); |
7725ccfd JH |
100 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
101 | } | |
102 | ||
5fbe25c7 | 103 | /* |
7725ccfd JH |
104 | * FC transport template entry, get SCSI host port ID. |
105 | */ | |
52f94b6f | 106 | static void |
7725ccfd JH |
107 | bfad_im_get_host_port_id(struct Scsi_Host *shost) |
108 | { | |
109 | struct bfad_im_port_s *im_port = | |
110 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
111 | struct bfad_port_s *port = im_port->port; | |
112 | ||
113 | fc_host_port_id(shost) = | |
f16a1750 | 114 | bfa_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port)); |
7725ccfd JH |
115 | } |
116 | ||
5fbe25c7 | 117 | /* |
7725ccfd JH |
118 | * FC transport template entry, get SCSI host port type. |
119 | */ | |
120 | static void | |
121 | bfad_im_get_host_port_type(struct Scsi_Host *shost) | |
122 | { | |
123 | struct bfad_im_port_s *im_port = | |
124 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
125 | struct bfad_s *bfad = im_port->bfad; | |
a36c61f9 | 126 | struct bfa_lport_attr_s port_attr; |
7725ccfd | 127 | |
a36c61f9 | 128 | bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); |
7725ccfd | 129 | |
a36c61f9 KG |
130 | switch (port_attr.port_type) { |
131 | case BFA_PORT_TYPE_NPORT: | |
7725ccfd JH |
132 | fc_host_port_type(shost) = FC_PORTTYPE_NPORT; |
133 | break; | |
a36c61f9 | 134 | case BFA_PORT_TYPE_NLPORT: |
7725ccfd JH |
135 | fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; |
136 | break; | |
a36c61f9 | 137 | case BFA_PORT_TYPE_P2P: |
7725ccfd JH |
138 | fc_host_port_type(shost) = FC_PORTTYPE_PTP; |
139 | break; | |
a36c61f9 | 140 | case BFA_PORT_TYPE_LPORT: |
7725ccfd JH |
141 | fc_host_port_type(shost) = FC_PORTTYPE_LPORT; |
142 | break; | |
143 | default: | |
144 | fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; | |
145 | break; | |
146 | } | |
147 | } | |
148 | ||
5fbe25c7 | 149 | /* |
7725ccfd JH |
150 | * FC transport template entry, get SCSI host port state. |
151 | */ | |
152 | static void | |
153 | bfad_im_get_host_port_state(struct Scsi_Host *shost) | |
154 | { | |
155 | struct bfad_im_port_s *im_port = | |
156 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
157 | struct bfad_s *bfad = im_port->bfad; | |
a36c61f9 | 158 | struct bfa_port_attr_s attr; |
7725ccfd | 159 | |
1c8a4c37 | 160 | bfa_fcport_get_attr(&bfad->bfa, &attr); |
7725ccfd JH |
161 | |
162 | switch (attr.port_state) { | |
a36c61f9 | 163 | case BFA_PORT_ST_LINKDOWN: |
7725ccfd JH |
164 | fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; |
165 | break; | |
a36c61f9 | 166 | case BFA_PORT_ST_LINKUP: |
7725ccfd JH |
167 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; |
168 | break; | |
a36c61f9 KG |
169 | case BFA_PORT_ST_DISABLED: |
170 | case BFA_PORT_ST_STOPPED: | |
171 | case BFA_PORT_ST_IOCDOWN: | |
172 | case BFA_PORT_ST_IOCDIS: | |
173 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | |
174 | break; | |
175 | case BFA_PORT_ST_UNINIT: | |
176 | case BFA_PORT_ST_ENABLING_QWAIT: | |
177 | case BFA_PORT_ST_ENABLING: | |
178 | case BFA_PORT_ST_DISABLING_QWAIT: | |
179 | case BFA_PORT_ST_DISABLING: | |
7725ccfd JH |
180 | default: |
181 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | |
182 | break; | |
183 | } | |
184 | } | |
185 | ||
5fbe25c7 | 186 | /* |
7725ccfd JH |
187 | * FC transport template entry, get SCSI host active fc4s. |
188 | */ | |
189 | static void | |
190 | bfad_im_get_host_active_fc4s(struct Scsi_Host *shost) | |
191 | { | |
192 | struct bfad_im_port_s *im_port = | |
193 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
194 | struct bfad_port_s *port = im_port->port; | |
195 | ||
196 | memset(fc_host_active_fc4s(shost), 0, | |
197 | sizeof(fc_host_active_fc4s(shost))); | |
198 | ||
a36c61f9 | 199 | if (port->supported_fc4s & BFA_LPORT_ROLE_FCP_IM) |
7725ccfd JH |
200 | fc_host_active_fc4s(shost)[2] = 1; |
201 | ||
7725ccfd JH |
202 | fc_host_active_fc4s(shost)[7] = 1; |
203 | } | |
204 | ||
5fbe25c7 | 205 | /* |
7725ccfd JH |
206 | * FC transport template entry, get SCSI host link speed. |
207 | */ | |
208 | static void | |
209 | bfad_im_get_host_speed(struct Scsi_Host *shost) | |
210 | { | |
211 | struct bfad_im_port_s *im_port = | |
212 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
213 | struct bfad_s *bfad = im_port->bfad; | |
a36c61f9 | 214 | struct bfa_port_attr_s attr; |
7725ccfd | 215 | |
1c8a4c37 | 216 | bfa_fcport_get_attr(&bfad->bfa, &attr); |
7725ccfd | 217 | switch (attr.speed) { |
a36c61f9 KG |
218 | case BFA_PORT_SPEED_10GBPS: |
219 | fc_host_speed(shost) = FC_PORTSPEED_10GBIT; | |
220 | break; | |
8b070b4a KG |
221 | case BFA_PORT_SPEED_16GBPS: |
222 | fc_host_speed(shost) = FC_PORTSPEED_16GBIT; | |
223 | break; | |
a36c61f9 | 224 | case BFA_PORT_SPEED_8GBPS: |
7725ccfd JH |
225 | fc_host_speed(shost) = FC_PORTSPEED_8GBIT; |
226 | break; | |
a36c61f9 | 227 | case BFA_PORT_SPEED_4GBPS: |
7725ccfd JH |
228 | fc_host_speed(shost) = FC_PORTSPEED_4GBIT; |
229 | break; | |
a36c61f9 | 230 | case BFA_PORT_SPEED_2GBPS: |
7725ccfd JH |
231 | fc_host_speed(shost) = FC_PORTSPEED_2GBIT; |
232 | break; | |
a36c61f9 | 233 | case BFA_PORT_SPEED_1GBPS: |
7725ccfd JH |
234 | fc_host_speed(shost) = FC_PORTSPEED_1GBIT; |
235 | break; | |
236 | default: | |
237 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | |
238 | break; | |
239 | } | |
240 | } | |
241 | ||
5fbe25c7 | 242 | /* |
7725ccfd JH |
243 | * FC transport template entry, get SCSI host port type. |
244 | */ | |
245 | static void | |
246 | bfad_im_get_host_fabric_name(struct Scsi_Host *shost) | |
247 | { | |
248 | struct bfad_im_port_s *im_port = | |
249 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
250 | struct bfad_port_s *port = im_port->port; | |
251 | wwn_t fabric_nwwn = 0; | |
252 | ||
a36c61f9 | 253 | fabric_nwwn = bfa_fcs_lport_get_fabric_name(port->fcs_port); |
7725ccfd | 254 | |
ba816ea8 | 255 | fc_host_fabric_name(shost) = cpu_to_be64(fabric_nwwn); |
7725ccfd JH |
256 | |
257 | } | |
258 | ||
5fbe25c7 | 259 | /* |
7725ccfd JH |
260 | * FC transport template entry, get BFAD statistics. |
261 | */ | |
262 | static struct fc_host_statistics * | |
263 | bfad_im_get_stats(struct Scsi_Host *shost) | |
264 | { | |
265 | struct bfad_im_port_s *im_port = | |
266 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
267 | struct bfad_s *bfad = im_port->bfad; | |
268 | struct bfad_hal_comp fcomp; | |
a36c61f9 | 269 | union bfa_port_stats_u *fcstats; |
7725ccfd JH |
270 | struct fc_host_statistics *hstats; |
271 | bfa_status_t rc; | |
272 | unsigned long flags; | |
273 | ||
a36c61f9 KG |
274 | fcstats = kzalloc(sizeof(union bfa_port_stats_u), GFP_KERNEL); |
275 | if (fcstats == NULL) | |
276 | return NULL; | |
277 | ||
7725ccfd JH |
278 | hstats = &bfad->link_stats; |
279 | init_completion(&fcomp.comp); | |
280 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
281 | memset(hstats, 0, sizeof(struct fc_host_statistics)); | |
a36c61f9 KG |
282 | rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa), |
283 | fcstats, bfad_hcb_comp, &fcomp); | |
7725ccfd JH |
284 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
285 | if (rc != BFA_STATUS_OK) | |
286 | return NULL; | |
287 | ||
288 | wait_for_completion(&fcomp.comp); | |
289 | ||
a36c61f9 KG |
290 | /* Fill the fc_host_statistics structure */ |
291 | hstats->seconds_since_last_reset = fcstats->fc.secs_reset; | |
292 | hstats->tx_frames = fcstats->fc.tx_frames; | |
293 | hstats->tx_words = fcstats->fc.tx_words; | |
294 | hstats->rx_frames = fcstats->fc.rx_frames; | |
295 | hstats->rx_words = fcstats->fc.rx_words; | |
296 | hstats->lip_count = fcstats->fc.lip_count; | |
297 | hstats->nos_count = fcstats->fc.nos_count; | |
298 | hstats->error_frames = fcstats->fc.error_frames; | |
299 | hstats->dumped_frames = fcstats->fc.dropped_frames; | |
300 | hstats->link_failure_count = fcstats->fc.link_failures; | |
301 | hstats->loss_of_sync_count = fcstats->fc.loss_of_syncs; | |
302 | hstats->loss_of_signal_count = fcstats->fc.loss_of_signals; | |
303 | hstats->prim_seq_protocol_err_count = fcstats->fc.primseq_errs; | |
304 | hstats->invalid_crc_count = fcstats->fc.invalid_crcs; | |
305 | ||
306 | kfree(fcstats); | |
7725ccfd JH |
307 | return hstats; |
308 | } | |
309 | ||
5fbe25c7 | 310 | /* |
7725ccfd JH |
311 | * FC transport template entry, reset BFAD statistics. |
312 | */ | |
313 | static void | |
314 | bfad_im_reset_stats(struct Scsi_Host *shost) | |
315 | { | |
316 | struct bfad_im_port_s *im_port = | |
317 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
318 | struct bfad_s *bfad = im_port->bfad; | |
319 | struct bfad_hal_comp fcomp; | |
320 | unsigned long flags; | |
321 | bfa_status_t rc; | |
322 | ||
323 | init_completion(&fcomp.comp); | |
324 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
ca8b4327 | 325 | rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp, |
a36c61f9 | 326 | &fcomp); |
7725ccfd JH |
327 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
328 | ||
329 | if (rc != BFA_STATUS_OK) | |
330 | return; | |
331 | ||
332 | wait_for_completion(&fcomp.comp); | |
333 | ||
334 | return; | |
335 | } | |
336 | ||
5fbe25c7 | 337 | /* |
7725ccfd JH |
338 | * FC transport template entry, get rport loss timeout. |
339 | */ | |
340 | static void | |
341 | bfad_im_get_rport_loss_tmo(struct fc_rport *rport) | |
342 | { | |
343 | struct bfad_itnim_data_s *itnim_data = rport->dd_data; | |
344 | struct bfad_itnim_s *itnim = itnim_data->itnim; | |
345 | struct bfad_s *bfad = itnim->im->bfad; | |
346 | unsigned long flags; | |
347 | ||
348 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
349 | rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); | |
350 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
351 | } | |
352 | ||
5fbe25c7 | 353 | /* |
7725ccfd JH |
354 | * FC transport template entry, set rport loss timeout. |
355 | */ | |
356 | static void | |
357 | bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) | |
358 | { | |
359 | struct bfad_itnim_data_s *itnim_data = rport->dd_data; | |
360 | struct bfad_itnim_s *itnim = itnim_data->itnim; | |
361 | struct bfad_s *bfad = itnim->im->bfad; | |
362 | unsigned long flags; | |
363 | ||
364 | if (timeout > 0) { | |
365 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
366 | bfa_fcpim_path_tov_set(&bfad->bfa, timeout); | |
367 | rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); | |
368 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
369 | } | |
370 | ||
371 | } | |
372 | ||
b504293f JH |
373 | static int |
374 | bfad_im_vport_create(struct fc_vport *fc_vport, bool disable) | |
375 | { | |
376 | char *vname = fc_vport->symbolic_name; | |
377 | struct Scsi_Host *shost = fc_vport->shost; | |
378 | struct bfad_im_port_s *im_port = | |
379 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
380 | struct bfad_s *bfad = im_port->bfad; | |
a36c61f9 KG |
381 | struct bfa_lport_cfg_s port_cfg; |
382 | struct bfad_vport_s *vp; | |
b504293f JH |
383 | int status = 0, rc; |
384 | unsigned long flags; | |
385 | ||
386 | memset(&port_cfg, 0, sizeof(port_cfg)); | |
d9883548 JH |
387 | u64_to_wwn(fc_vport->node_name, (u8 *)&port_cfg.nwwn); |
388 | u64_to_wwn(fc_vport->port_name, (u8 *)&port_cfg.pwwn); | |
b504293f JH |
389 | if (strlen(vname) > 0) |
390 | strcpy((char *)&port_cfg.sym_name, vname); | |
a36c61f9 | 391 | port_cfg.roles = BFA_LPORT_ROLE_FCP_IM; |
b504293f | 392 | |
d9883548 | 393 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
a36c61f9 KG |
394 | list_for_each_entry(vp, &bfad->pbc_vport_list, list_entry) { |
395 | if (port_cfg.pwwn == | |
396 | vp->fcs_vport.lport.port_cfg.pwwn) { | |
397 | port_cfg.preboot_vp = | |
398 | vp->fcs_vport.lport.port_cfg.preboot_vp; | |
d9883548 JH |
399 | break; |
400 | } | |
401 | } | |
402 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
403 | ||
404 | rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev); | |
b504293f | 405 | if (rc == BFA_STATUS_OK) { |
d9883548 | 406 | struct bfad_vport_s *vport; |
b504293f JH |
407 | struct bfa_fcs_vport_s *fcs_vport; |
408 | struct Scsi_Host *vshost; | |
409 | ||
410 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
411 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, | |
412 | port_cfg.pwwn); | |
d9883548 JH |
413 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
414 | if (fcs_vport == NULL) | |
b504293f | 415 | return VPCERR_BAD_WWN; |
b504293f JH |
416 | |
417 | fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE); | |
418 | if (disable) { | |
d9883548 | 419 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
b504293f | 420 | bfa_fcs_vport_stop(fcs_vport); |
d9883548 | 421 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
b504293f JH |
422 | fc_vport_set_state(fc_vport, FC_VPORT_DISABLED); |
423 | } | |
b504293f JH |
424 | |
425 | vport = fcs_vport->vport_drv; | |
426 | vshost = vport->drv_port.im_port->shost; | |
d9883548 JH |
427 | fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn); |
428 | fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn); | |
6192bd7c KG |
429 | fc_host_supported_classes(vshost) = FC_COS_CLASS3; |
430 | ||
431 | memset(fc_host_supported_fc4s(vshost), 0, | |
432 | sizeof(fc_host_supported_fc4s(vshost))); | |
433 | ||
434 | /* For FCP type 0x08 */ | |
435 | if (supported_fc4s & BFA_LPORT_ROLE_FCP_IM) | |
436 | fc_host_supported_fc4s(vshost)[2] = 1; | |
437 | ||
438 | /* For fibre channel services type 0x20 */ | |
439 | fc_host_supported_fc4s(vshost)[7] = 1; | |
440 | ||
441 | fc_host_supported_speeds(vshost) = | |
442 | bfad_im_supported_speeds(&bfad->bfa); | |
443 | fc_host_maxframe_size(vshost) = | |
444 | bfa_fcport_get_maxfrsize(&bfad->bfa); | |
445 | ||
b504293f JH |
446 | fc_vport->dd_data = vport; |
447 | vport->drv_port.im_port->fc_vport = fc_vport; | |
b504293f JH |
448 | } else if (rc == BFA_STATUS_INVALID_WWN) |
449 | return VPCERR_BAD_WWN; | |
450 | else if (rc == BFA_STATUS_VPORT_EXISTS) | |
451 | return VPCERR_BAD_WWN; | |
452 | else if (rc == BFA_STATUS_VPORT_MAX) | |
453 | return VPCERR_NO_FABRIC_SUPP; | |
454 | else if (rc == BFA_STATUS_VPORT_WWN_BP) | |
455 | return VPCERR_BAD_WWN; | |
d9883548 | 456 | else |
b504293f JH |
457 | return FC_VPORT_FAILED; |
458 | ||
459 | return status; | |
460 | } | |
461 | ||
acea2415 KG |
462 | int |
463 | bfad_im_issue_fc_host_lip(struct Scsi_Host *shost) | |
464 | { | |
465 | struct bfad_im_port_s *im_port = | |
466 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
467 | struct bfad_s *bfad = im_port->bfad; | |
468 | struct bfad_hal_comp fcomp; | |
469 | unsigned long flags; | |
470 | uint32_t status; | |
471 | ||
472 | init_completion(&fcomp.comp); | |
473 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
474 | status = bfa_port_disable(&bfad->bfa.modules.port, | |
475 | bfad_hcb_comp, &fcomp); | |
476 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
477 | ||
478 | if (status != BFA_STATUS_OK) | |
479 | return -EIO; | |
480 | ||
481 | wait_for_completion(&fcomp.comp); | |
482 | if (fcomp.status != BFA_STATUS_OK) | |
483 | return -EIO; | |
484 | ||
485 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
486 | status = bfa_port_enable(&bfad->bfa.modules.port, | |
487 | bfad_hcb_comp, &fcomp); | |
488 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
489 | if (status != BFA_STATUS_OK) | |
490 | return -EIO; | |
491 | ||
492 | wait_for_completion(&fcomp.comp); | |
493 | if (fcomp.status != BFA_STATUS_OK) | |
494 | return -EIO; | |
495 | ||
496 | return 0; | |
497 | } | |
498 | ||
b504293f JH |
499 | static int |
500 | bfad_im_vport_delete(struct fc_vport *fc_vport) | |
501 | { | |
502 | struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data; | |
503 | struct bfad_im_port_s *im_port = | |
504 | (struct bfad_im_port_s *) vport->drv_port.im_port; | |
505 | struct bfad_s *bfad = im_port->bfad; | |
506 | struct bfad_port_s *port; | |
507 | struct bfa_fcs_vport_s *fcs_vport; | |
508 | struct Scsi_Host *vshost; | |
509 | wwn_t pwwn; | |
510 | int rc; | |
511 | unsigned long flags; | |
512 | struct completion fcomp; | |
513 | ||
ff179e0f KG |
514 | if (im_port->flags & BFAD_PORT_DELETE) { |
515 | bfad_scsi_host_free(bfad, im_port); | |
516 | list_del(&vport->list_entry); | |
17c201b3 | 517 | kfree(vport); |
ff179e0f KG |
518 | return 0; |
519 | } | |
b504293f JH |
520 | |
521 | port = im_port->port; | |
522 | ||
523 | vshost = vport->drv_port.im_port->shost; | |
d9883548 | 524 | u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn); |
b504293f JH |
525 | |
526 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
527 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); | |
528 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
529 | ||
530 | if (fcs_vport == NULL) | |
531 | return VPCERR_BAD_WWN; | |
532 | ||
533 | vport->drv_port.flags |= BFAD_PORT_DELETE; | |
534 | ||
535 | vport->comp_del = &fcomp; | |
536 | init_completion(vport->comp_del); | |
537 | ||
538 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
539 | rc = bfa_fcs_vport_delete(&vport->fcs_vport); | |
540 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
541 | ||
c54d557c JH |
542 | if (rc == BFA_STATUS_PBC) { |
543 | vport->drv_port.flags &= ~BFAD_PORT_DELETE; | |
544 | vport->comp_del = NULL; | |
d9883548 | 545 | return -1; |
c54d557c | 546 | } |
d9883548 | 547 | |
b504293f JH |
548 | wait_for_completion(vport->comp_del); |
549 | ||
f16a1750 | 550 | bfad_scsi_host_free(bfad, im_port); |
5b7db7af | 551 | list_del(&vport->list_entry); |
b504293f JH |
552 | kfree(vport); |
553 | ||
554 | return 0; | |
555 | } | |
556 | ||
557 | static int | |
558 | bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable) | |
559 | { | |
560 | struct bfad_vport_s *vport; | |
561 | struct bfad_s *bfad; | |
562 | struct bfa_fcs_vport_s *fcs_vport; | |
563 | struct Scsi_Host *vshost; | |
564 | wwn_t pwwn; | |
565 | unsigned long flags; | |
566 | ||
567 | vport = (struct bfad_vport_s *)fc_vport->dd_data; | |
568 | bfad = vport->drv_port.bfad; | |
569 | vshost = vport->drv_port.im_port->shost; | |
d9883548 | 570 | u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn); |
b504293f JH |
571 | |
572 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
573 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); | |
574 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
575 | ||
576 | if (fcs_vport == NULL) | |
577 | return VPCERR_BAD_WWN; | |
578 | ||
579 | if (disable) { | |
580 | bfa_fcs_vport_stop(fcs_vport); | |
581 | fc_vport_set_state(fc_vport, FC_VPORT_DISABLED); | |
582 | } else { | |
583 | bfa_fcs_vport_start(fcs_vport); | |
584 | fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE); | |
585 | } | |
586 | ||
587 | return 0; | |
588 | } | |
589 | ||
7725ccfd JH |
590 | struct fc_function_template bfad_im_fc_function_template = { |
591 | ||
592 | /* Target dynamic attributes */ | |
593 | .get_starget_port_id = bfad_im_get_starget_port_id, | |
594 | .show_starget_port_id = 1, | |
595 | .get_starget_node_name = bfad_im_get_starget_node_name, | |
596 | .show_starget_node_name = 1, | |
597 | .get_starget_port_name = bfad_im_get_starget_port_name, | |
598 | .show_starget_port_name = 1, | |
b504293f JH |
599 | |
600 | /* Host dynamic attribute */ | |
601 | .get_host_port_id = bfad_im_get_host_port_id, | |
602 | .show_host_port_id = 1, | |
603 | ||
604 | /* Host fixed attributes */ | |
605 | .show_host_node_name = 1, | |
606 | .show_host_port_name = 1, | |
607 | .show_host_supported_classes = 1, | |
608 | .show_host_supported_fc4s = 1, | |
609 | .show_host_supported_speeds = 1, | |
610 | .show_host_maxframe_size = 1, | |
611 | ||
612 | /* More host dynamic attributes */ | |
613 | .show_host_port_type = 1, | |
614 | .get_host_port_type = bfad_im_get_host_port_type, | |
615 | .show_host_port_state = 1, | |
616 | .get_host_port_state = bfad_im_get_host_port_state, | |
617 | .show_host_active_fc4s = 1, | |
618 | .get_host_active_fc4s = bfad_im_get_host_active_fc4s, | |
619 | .show_host_speed = 1, | |
620 | .get_host_speed = bfad_im_get_host_speed, | |
621 | .show_host_fabric_name = 1, | |
622 | .get_host_fabric_name = bfad_im_get_host_fabric_name, | |
623 | ||
624 | .show_host_symbolic_name = 1, | |
625 | ||
626 | /* Statistics */ | |
627 | .get_fc_host_stats = bfad_im_get_stats, | |
628 | .reset_fc_host_stats = bfad_im_reset_stats, | |
629 | ||
630 | /* Allocation length for host specific data */ | |
631 | .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), | |
632 | ||
633 | /* Remote port fixed attributes */ | |
634 | .show_rport_maxframe_size = 1, | |
635 | .show_rport_supported_classes = 1, | |
636 | .show_rport_dev_loss_tmo = 1, | |
637 | .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, | |
638 | .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, | |
acea2415 | 639 | .issue_fc_host_lip = bfad_im_issue_fc_host_lip, |
b504293f JH |
640 | .vport_create = bfad_im_vport_create, |
641 | .vport_delete = bfad_im_vport_delete, | |
642 | .vport_disable = bfad_im_vport_disable, | |
b85daafe KG |
643 | .bsg_request = bfad_im_bsg_request, |
644 | .bsg_timeout = bfad_im_bsg_timeout, | |
b504293f JH |
645 | }; |
646 | ||
647 | struct fc_function_template bfad_im_vport_fc_function_template = { | |
648 | ||
649 | /* Target dynamic attributes */ | |
650 | .get_starget_port_id = bfad_im_get_starget_port_id, | |
651 | .show_starget_port_id = 1, | |
652 | .get_starget_node_name = bfad_im_get_starget_node_name, | |
653 | .show_starget_node_name = 1, | |
654 | .get_starget_port_name = bfad_im_get_starget_port_name, | |
655 | .show_starget_port_name = 1, | |
7725ccfd JH |
656 | |
657 | /* Host dynamic attribute */ | |
658 | .get_host_port_id = bfad_im_get_host_port_id, | |
659 | .show_host_port_id = 1, | |
660 | ||
661 | /* Host fixed attributes */ | |
662 | .show_host_node_name = 1, | |
663 | .show_host_port_name = 1, | |
664 | .show_host_supported_classes = 1, | |
665 | .show_host_supported_fc4s = 1, | |
666 | .show_host_supported_speeds = 1, | |
667 | .show_host_maxframe_size = 1, | |
668 | ||
669 | /* More host dynamic attributes */ | |
670 | .show_host_port_type = 1, | |
671 | .get_host_port_type = bfad_im_get_host_port_type, | |
672 | .show_host_port_state = 1, | |
673 | .get_host_port_state = bfad_im_get_host_port_state, | |
674 | .show_host_active_fc4s = 1, | |
675 | .get_host_active_fc4s = bfad_im_get_host_active_fc4s, | |
676 | .show_host_speed = 1, | |
677 | .get_host_speed = bfad_im_get_host_speed, | |
678 | .show_host_fabric_name = 1, | |
679 | .get_host_fabric_name = bfad_im_get_host_fabric_name, | |
680 | ||
681 | .show_host_symbolic_name = 1, | |
682 | ||
683 | /* Statistics */ | |
684 | .get_fc_host_stats = bfad_im_get_stats, | |
685 | .reset_fc_host_stats = bfad_im_reset_stats, | |
686 | ||
687 | /* Allocation length for host specific data */ | |
688 | .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), | |
689 | ||
690 | /* Remote port fixed attributes */ | |
691 | .show_rport_maxframe_size = 1, | |
692 | .show_rport_supported_classes = 1, | |
693 | .show_rport_dev_loss_tmo = 1, | |
694 | .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, | |
695 | .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, | |
696 | }; | |
697 | ||
5fbe25c7 | 698 | /* |
7725ccfd JH |
699 | * Scsi_Host_attrs SCSI host attributes |
700 | */ | |
701 | static ssize_t | |
702 | bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr, | |
703 | char *buf) | |
704 | { | |
705 | struct Scsi_Host *shost = class_to_shost(dev); | |
706 | struct bfad_im_port_s *im_port = | |
707 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 708 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 709 | char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; |
7725ccfd | 710 | |
0a4b1fc0 KG |
711 | bfa_get_adapter_serial_num(&bfad->bfa, serial_num); |
712 | return snprintf(buf, PAGE_SIZE, "%s\n", serial_num); | |
7725ccfd JH |
713 | } |
714 | ||
715 | static ssize_t | |
716 | bfad_im_model_show(struct device *dev, struct device_attribute *attr, | |
717 | char *buf) | |
718 | { | |
719 | struct Scsi_Host *shost = class_to_shost(dev); | |
720 | struct bfad_im_port_s *im_port = | |
721 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 722 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 723 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; |
7725ccfd | 724 | |
0a4b1fc0 KG |
725 | bfa_get_adapter_model(&bfad->bfa, model); |
726 | return snprintf(buf, PAGE_SIZE, "%s\n", model); | |
7725ccfd JH |
727 | } |
728 | ||
729 | static ssize_t | |
730 | bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, | |
731 | char *buf) | |
732 | { | |
733 | struct Scsi_Host *shost = class_to_shost(dev); | |
734 | struct bfad_im_port_s *im_port = | |
735 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 KG |
736 | struct bfad_s *bfad = im_port->bfad; |
737 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; | |
0a4b1fc0 | 738 | char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; |
75332a70 | 739 | int nports = 0; |
7725ccfd | 740 | |
a36c61f9 | 741 | bfa_get_adapter_model(&bfad->bfa, model); |
75332a70 | 742 | nports = bfa_get_nports(&bfad->bfa); |
a36c61f9 KG |
743 | if (!strcmp(model, "Brocade-425")) |
744 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
745 | "Brocade 4Gbps PCIe dual port FC HBA"); | |
746 | else if (!strcmp(model, "Brocade-825")) | |
747 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
748 | "Brocade 8Gbps PCIe dual port FC HBA"); | |
749 | else if (!strcmp(model, "Brocade-42B")) | |
750 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 751 | "Brocade 4Gbps PCIe dual port FC HBA for HP"); |
a36c61f9 KG |
752 | else if (!strcmp(model, "Brocade-82B")) |
753 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 754 | "Brocade 8Gbps PCIe dual port FC HBA for HP"); |
a36c61f9 KG |
755 | else if (!strcmp(model, "Brocade-1010")) |
756 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
757 | "Brocade 10Gbps single port CNA"); | |
758 | else if (!strcmp(model, "Brocade-1020")) | |
759 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
760 | "Brocade 10Gbps dual port CNA"); | |
761 | else if (!strcmp(model, "Brocade-1007")) | |
762 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 763 | "Brocade 10Gbps CNA for IBM Blade Center"); |
a36c61f9 KG |
764 | else if (!strcmp(model, "Brocade-415")) |
765 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
766 | "Brocade 4Gbps PCIe single port FC HBA"); | |
767 | else if (!strcmp(model, "Brocade-815")) | |
768 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
769 | "Brocade 8Gbps PCIe single port FC HBA"); | |
770 | else if (!strcmp(model, "Brocade-41B")) | |
771 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 772 | "Brocade 4Gbps PCIe single port FC HBA for HP"); |
a36c61f9 KG |
773 | else if (!strcmp(model, "Brocade-81B")) |
774 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 775 | "Brocade 8Gbps PCIe single port FC HBA for HP"); |
a36c61f9 KG |
776 | else if (!strcmp(model, "Brocade-804")) |
777 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 778 | "Brocade 8Gbps FC HBA for HP Bladesystem C-class"); |
9d8ad782 | 779 | else if (!strcmp(model, "Brocade-1741")) |
a36c61f9 | 780 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, |
75332a70 | 781 | "Brocade 10Gbps CNA for Dell M-Series Blade Servers"); |
9d8ad782 | 782 | else if (strstr(model, "Brocade-1860")) { |
75332a70 KG |
783 | if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc)) |
784 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
785 | "Brocade 10Gbps single port CNA"); | |
786 | else if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) | |
787 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
788 | "Brocade 16Gbps PCIe single port FC HBA"); | |
789 | else if (nports == 2 && bfa_ioc_is_cna(&bfad->bfa.ioc)) | |
790 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
791 | "Brocade 10Gbps dual port CNA"); | |
792 | else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) | |
793 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
794 | "Brocade 16Gbps PCIe dual port FC HBA"); | |
795 | } else | |
a36c61f9 KG |
796 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, |
797 | "Invalid Model"); | |
798 | ||
0a4b1fc0 | 799 | return snprintf(buf, PAGE_SIZE, "%s\n", model_descr); |
7725ccfd JH |
800 | } |
801 | ||
802 | static ssize_t | |
803 | bfad_im_node_name_show(struct device *dev, struct device_attribute *attr, | |
804 | char *buf) | |
805 | { | |
806 | struct Scsi_Host *shost = class_to_shost(dev); | |
807 | struct bfad_im_port_s *im_port = | |
808 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
809 | struct bfad_port_s *port = im_port->port; | |
810 | u64 nwwn; | |
811 | ||
a36c61f9 | 812 | nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port); |
ba816ea8 | 813 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", cpu_to_be64(nwwn)); |
7725ccfd JH |
814 | } |
815 | ||
816 | static ssize_t | |
817 | bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, | |
818 | char *buf) | |
819 | { | |
820 | struct Scsi_Host *shost = class_to_shost(dev); | |
821 | struct bfad_im_port_s *im_port = | |
822 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 KG |
823 | struct bfad_s *bfad = im_port->bfad; |
824 | struct bfa_lport_attr_s port_attr; | |
825 | char symname[BFA_SYMNAME_MAXLEN]; | |
7725ccfd | 826 | |
a36c61f9 KG |
827 | bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); |
828 | strncpy(symname, port_attr.port_cfg.sym_name.symname, | |
829 | BFA_SYMNAME_MAXLEN); | |
830 | return snprintf(buf, PAGE_SIZE, "%s\n", symname); | |
7725ccfd JH |
831 | } |
832 | ||
833 | static ssize_t | |
834 | bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, | |
835 | char *buf) | |
836 | { | |
837 | struct Scsi_Host *shost = class_to_shost(dev); | |
838 | struct bfad_im_port_s *im_port = | |
839 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 840 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 841 | char hw_ver[BFA_VERSION_LEN]; |
7725ccfd | 842 | |
0a4b1fc0 KG |
843 | bfa_get_pci_chip_rev(&bfad->bfa, hw_ver); |
844 | return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver); | |
7725ccfd JH |
845 | } |
846 | ||
847 | static ssize_t | |
848 | bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, | |
849 | char *buf) | |
850 | { | |
851 | return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION); | |
852 | } | |
853 | ||
854 | static ssize_t | |
855 | bfad_im_optionrom_version_show(struct device *dev, | |
856 | struct device_attribute *attr, char *buf) | |
857 | { | |
858 | struct Scsi_Host *shost = class_to_shost(dev); | |
859 | struct bfad_im_port_s *im_port = | |
860 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 861 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 862 | char optrom_ver[BFA_VERSION_LEN]; |
7725ccfd | 863 | |
0a4b1fc0 KG |
864 | bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver); |
865 | return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver); | |
7725ccfd JH |
866 | } |
867 | ||
868 | static ssize_t | |
869 | bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr, | |
870 | char *buf) | |
871 | { | |
872 | struct Scsi_Host *shost = class_to_shost(dev); | |
873 | struct bfad_im_port_s *im_port = | |
874 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 875 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 876 | char fw_ver[BFA_VERSION_LEN]; |
7725ccfd | 877 | |
0a4b1fc0 KG |
878 | bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); |
879 | return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver); | |
7725ccfd JH |
880 | } |
881 | ||
882 | static ssize_t | |
883 | bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, | |
884 | char *buf) | |
885 | { | |
886 | struct Scsi_Host *shost = class_to_shost(dev); | |
887 | struct bfad_im_port_s *im_port = | |
888 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 889 | struct bfad_s *bfad = im_port->bfad; |
7725ccfd | 890 | |
0a4b1fc0 | 891 | return snprintf(buf, PAGE_SIZE, "%d\n", |
a36c61f9 | 892 | bfa_get_nports(&bfad->bfa)); |
7725ccfd JH |
893 | } |
894 | ||
895 | static ssize_t | |
896 | bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, | |
897 | char *buf) | |
898 | { | |
899 | return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME); | |
900 | } | |
901 | ||
902 | static ssize_t | |
903 | bfad_im_num_of_discovered_ports_show(struct device *dev, | |
904 | struct device_attribute *attr, char *buf) | |
905 | { | |
906 | struct Scsi_Host *shost = class_to_shost(dev); | |
907 | struct bfad_im_port_s *im_port = | |
908 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
909 | struct bfad_port_s *port = im_port->port; | |
910 | struct bfad_s *bfad = im_port->bfad; | |
911 | int nrports = 2048; | |
912 | wwn_t *rports = NULL; | |
913 | unsigned long flags; | |
914 | ||
915 | rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC); | |
916 | if (rports == NULL) | |
a36c61f9 | 917 | return snprintf(buf, PAGE_SIZE, "Failed\n"); |
7725ccfd JH |
918 | |
919 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
a36c61f9 | 920 | bfa_fcs_lport_get_rports(port->fcs_port, rports, &nrports); |
7725ccfd JH |
921 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
922 | kfree(rports); | |
923 | ||
924 | return snprintf(buf, PAGE_SIZE, "%d\n", nrports); | |
925 | } | |
926 | ||
927 | static DEVICE_ATTR(serial_number, S_IRUGO, | |
928 | bfad_im_serial_num_show, NULL); | |
929 | static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL); | |
930 | static DEVICE_ATTR(model_description, S_IRUGO, | |
931 | bfad_im_model_desc_show, NULL); | |
932 | static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL); | |
933 | static DEVICE_ATTR(symbolic_name, S_IRUGO, | |
934 | bfad_im_symbolic_name_show, NULL); | |
935 | static DEVICE_ATTR(hardware_version, S_IRUGO, | |
936 | bfad_im_hw_version_show, NULL); | |
937 | static DEVICE_ATTR(driver_version, S_IRUGO, | |
938 | bfad_im_drv_version_show, NULL); | |
939 | static DEVICE_ATTR(option_rom_version, S_IRUGO, | |
940 | bfad_im_optionrom_version_show, NULL); | |
941 | static DEVICE_ATTR(firmware_version, S_IRUGO, | |
942 | bfad_im_fw_version_show, NULL); | |
943 | static DEVICE_ATTR(number_of_ports, S_IRUGO, | |
944 | bfad_im_num_of_ports_show, NULL); | |
945 | static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL); | |
946 | static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO, | |
947 | bfad_im_num_of_discovered_ports_show, NULL); | |
948 | ||
949 | struct device_attribute *bfad_im_host_attrs[] = { | |
950 | &dev_attr_serial_number, | |
951 | &dev_attr_model, | |
952 | &dev_attr_model_description, | |
953 | &dev_attr_node_name, | |
954 | &dev_attr_symbolic_name, | |
955 | &dev_attr_hardware_version, | |
956 | &dev_attr_driver_version, | |
957 | &dev_attr_option_rom_version, | |
958 | &dev_attr_firmware_version, | |
959 | &dev_attr_number_of_ports, | |
960 | &dev_attr_driver_name, | |
961 | &dev_attr_number_of_discovered_ports, | |
962 | NULL, | |
963 | }; | |
964 | ||
965 | struct device_attribute *bfad_im_vport_attrs[] = { | |
a36c61f9 KG |
966 | &dev_attr_serial_number, |
967 | &dev_attr_model, | |
968 | &dev_attr_model_description, | |
969 | &dev_attr_node_name, | |
970 | &dev_attr_symbolic_name, | |
971 | &dev_attr_hardware_version, | |
972 | &dev_attr_driver_version, | |
973 | &dev_attr_option_rom_version, | |
974 | &dev_attr_firmware_version, | |
975 | &dev_attr_number_of_ports, | |
976 | &dev_attr_driver_name, | |
977 | &dev_attr_number_of_discovered_ports, | |
978 | NULL, | |
7725ccfd JH |
979 | }; |
980 | ||
981 |