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