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); | |
b504293f JH |
429 | fc_vport->dd_data = vport; |
430 | vport->drv_port.im_port->fc_vport = fc_vport; | |
b504293f JH |
431 | } else if (rc == BFA_STATUS_INVALID_WWN) |
432 | return VPCERR_BAD_WWN; | |
433 | else if (rc == BFA_STATUS_VPORT_EXISTS) | |
434 | return VPCERR_BAD_WWN; | |
435 | else if (rc == BFA_STATUS_VPORT_MAX) | |
436 | return VPCERR_NO_FABRIC_SUPP; | |
437 | else if (rc == BFA_STATUS_VPORT_WWN_BP) | |
438 | return VPCERR_BAD_WWN; | |
d9883548 | 439 | else |
b504293f JH |
440 | return FC_VPORT_FAILED; |
441 | ||
442 | return status; | |
443 | } | |
444 | ||
445 | static int | |
446 | bfad_im_vport_delete(struct fc_vport *fc_vport) | |
447 | { | |
448 | struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data; | |
449 | struct bfad_im_port_s *im_port = | |
450 | (struct bfad_im_port_s *) vport->drv_port.im_port; | |
451 | struct bfad_s *bfad = im_port->bfad; | |
452 | struct bfad_port_s *port; | |
453 | struct bfa_fcs_vport_s *fcs_vport; | |
454 | struct Scsi_Host *vshost; | |
455 | wwn_t pwwn; | |
456 | int rc; | |
457 | unsigned long flags; | |
458 | struct completion fcomp; | |
459 | ||
460 | if (im_port->flags & BFAD_PORT_DELETE) | |
461 | goto free_scsi_host; | |
462 | ||
463 | port = im_port->port; | |
464 | ||
465 | vshost = vport->drv_port.im_port->shost; | |
d9883548 | 466 | u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn); |
b504293f JH |
467 | |
468 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
469 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); | |
470 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
471 | ||
472 | if (fcs_vport == NULL) | |
473 | return VPCERR_BAD_WWN; | |
474 | ||
475 | vport->drv_port.flags |= BFAD_PORT_DELETE; | |
476 | ||
477 | vport->comp_del = &fcomp; | |
478 | init_completion(vport->comp_del); | |
479 | ||
480 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
481 | rc = bfa_fcs_vport_delete(&vport->fcs_vport); | |
482 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
483 | ||
c54d557c JH |
484 | if (rc == BFA_STATUS_PBC) { |
485 | vport->drv_port.flags &= ~BFAD_PORT_DELETE; | |
486 | vport->comp_del = NULL; | |
d9883548 | 487 | return -1; |
c54d557c | 488 | } |
d9883548 | 489 | |
b504293f JH |
490 | wait_for_completion(vport->comp_del); |
491 | ||
492 | free_scsi_host: | |
f16a1750 | 493 | bfad_scsi_host_free(bfad, im_port); |
b504293f JH |
494 | |
495 | kfree(vport); | |
496 | ||
497 | return 0; | |
498 | } | |
499 | ||
500 | static int | |
501 | bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable) | |
502 | { | |
503 | struct bfad_vport_s *vport; | |
504 | struct bfad_s *bfad; | |
505 | struct bfa_fcs_vport_s *fcs_vport; | |
506 | struct Scsi_Host *vshost; | |
507 | wwn_t pwwn; | |
508 | unsigned long flags; | |
509 | ||
510 | vport = (struct bfad_vport_s *)fc_vport->dd_data; | |
511 | bfad = vport->drv_port.bfad; | |
512 | vshost = vport->drv_port.im_port->shost; | |
d9883548 | 513 | u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn); |
b504293f JH |
514 | |
515 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
516 | fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); | |
517 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
518 | ||
519 | if (fcs_vport == NULL) | |
520 | return VPCERR_BAD_WWN; | |
521 | ||
522 | if (disable) { | |
523 | bfa_fcs_vport_stop(fcs_vport); | |
524 | fc_vport_set_state(fc_vport, FC_VPORT_DISABLED); | |
525 | } else { | |
526 | bfa_fcs_vport_start(fcs_vport); | |
527 | fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE); | |
528 | } | |
529 | ||
530 | return 0; | |
531 | } | |
532 | ||
7725ccfd JH |
533 | struct fc_function_template bfad_im_fc_function_template = { |
534 | ||
535 | /* Target dynamic attributes */ | |
536 | .get_starget_port_id = bfad_im_get_starget_port_id, | |
537 | .show_starget_port_id = 1, | |
538 | .get_starget_node_name = bfad_im_get_starget_node_name, | |
539 | .show_starget_node_name = 1, | |
540 | .get_starget_port_name = bfad_im_get_starget_port_name, | |
541 | .show_starget_port_name = 1, | |
b504293f JH |
542 | |
543 | /* Host dynamic attribute */ | |
544 | .get_host_port_id = bfad_im_get_host_port_id, | |
545 | .show_host_port_id = 1, | |
546 | ||
547 | /* Host fixed attributes */ | |
548 | .show_host_node_name = 1, | |
549 | .show_host_port_name = 1, | |
550 | .show_host_supported_classes = 1, | |
551 | .show_host_supported_fc4s = 1, | |
552 | .show_host_supported_speeds = 1, | |
553 | .show_host_maxframe_size = 1, | |
554 | ||
555 | /* More host dynamic attributes */ | |
556 | .show_host_port_type = 1, | |
557 | .get_host_port_type = bfad_im_get_host_port_type, | |
558 | .show_host_port_state = 1, | |
559 | .get_host_port_state = bfad_im_get_host_port_state, | |
560 | .show_host_active_fc4s = 1, | |
561 | .get_host_active_fc4s = bfad_im_get_host_active_fc4s, | |
562 | .show_host_speed = 1, | |
563 | .get_host_speed = bfad_im_get_host_speed, | |
564 | .show_host_fabric_name = 1, | |
565 | .get_host_fabric_name = bfad_im_get_host_fabric_name, | |
566 | ||
567 | .show_host_symbolic_name = 1, | |
568 | ||
569 | /* Statistics */ | |
570 | .get_fc_host_stats = bfad_im_get_stats, | |
571 | .reset_fc_host_stats = bfad_im_reset_stats, | |
572 | ||
573 | /* Allocation length for host specific data */ | |
574 | .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), | |
575 | ||
576 | /* Remote port fixed attributes */ | |
577 | .show_rport_maxframe_size = 1, | |
578 | .show_rport_supported_classes = 1, | |
579 | .show_rport_dev_loss_tmo = 1, | |
580 | .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, | |
581 | .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, | |
582 | ||
583 | .vport_create = bfad_im_vport_create, | |
584 | .vport_delete = bfad_im_vport_delete, | |
585 | .vport_disable = bfad_im_vport_disable, | |
586 | }; | |
587 | ||
588 | struct fc_function_template bfad_im_vport_fc_function_template = { | |
589 | ||
590 | /* Target dynamic attributes */ | |
591 | .get_starget_port_id = bfad_im_get_starget_port_id, | |
592 | .show_starget_port_id = 1, | |
593 | .get_starget_node_name = bfad_im_get_starget_node_name, | |
594 | .show_starget_node_name = 1, | |
595 | .get_starget_port_name = bfad_im_get_starget_port_name, | |
596 | .show_starget_port_name = 1, | |
7725ccfd JH |
597 | |
598 | /* Host dynamic attribute */ | |
599 | .get_host_port_id = bfad_im_get_host_port_id, | |
600 | .show_host_port_id = 1, | |
601 | ||
602 | /* Host fixed attributes */ | |
603 | .show_host_node_name = 1, | |
604 | .show_host_port_name = 1, | |
605 | .show_host_supported_classes = 1, | |
606 | .show_host_supported_fc4s = 1, | |
607 | .show_host_supported_speeds = 1, | |
608 | .show_host_maxframe_size = 1, | |
609 | ||
610 | /* More host dynamic attributes */ | |
611 | .show_host_port_type = 1, | |
612 | .get_host_port_type = bfad_im_get_host_port_type, | |
613 | .show_host_port_state = 1, | |
614 | .get_host_port_state = bfad_im_get_host_port_state, | |
615 | .show_host_active_fc4s = 1, | |
616 | .get_host_active_fc4s = bfad_im_get_host_active_fc4s, | |
617 | .show_host_speed = 1, | |
618 | .get_host_speed = bfad_im_get_host_speed, | |
619 | .show_host_fabric_name = 1, | |
620 | .get_host_fabric_name = bfad_im_get_host_fabric_name, | |
621 | ||
622 | .show_host_symbolic_name = 1, | |
623 | ||
624 | /* Statistics */ | |
625 | .get_fc_host_stats = bfad_im_get_stats, | |
626 | .reset_fc_host_stats = bfad_im_reset_stats, | |
627 | ||
628 | /* Allocation length for host specific data */ | |
629 | .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), | |
630 | ||
631 | /* Remote port fixed attributes */ | |
632 | .show_rport_maxframe_size = 1, | |
633 | .show_rport_supported_classes = 1, | |
634 | .show_rport_dev_loss_tmo = 1, | |
635 | .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, | |
636 | .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, | |
637 | }; | |
638 | ||
5fbe25c7 | 639 | /* |
7725ccfd JH |
640 | * Scsi_Host_attrs SCSI host attributes |
641 | */ | |
642 | static ssize_t | |
643 | bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr, | |
644 | char *buf) | |
645 | { | |
646 | struct Scsi_Host *shost = class_to_shost(dev); | |
647 | struct bfad_im_port_s *im_port = | |
648 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 649 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 650 | char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; |
7725ccfd | 651 | |
0a4b1fc0 KG |
652 | bfa_get_adapter_serial_num(&bfad->bfa, serial_num); |
653 | return snprintf(buf, PAGE_SIZE, "%s\n", serial_num); | |
7725ccfd JH |
654 | } |
655 | ||
656 | static ssize_t | |
657 | bfad_im_model_show(struct device *dev, struct device_attribute *attr, | |
658 | char *buf) | |
659 | { | |
660 | struct Scsi_Host *shost = class_to_shost(dev); | |
661 | struct bfad_im_port_s *im_port = | |
662 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 663 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 664 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; |
7725ccfd | 665 | |
0a4b1fc0 KG |
666 | bfa_get_adapter_model(&bfad->bfa, model); |
667 | return snprintf(buf, PAGE_SIZE, "%s\n", model); | |
7725ccfd JH |
668 | } |
669 | ||
670 | static ssize_t | |
671 | bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, | |
672 | char *buf) | |
673 | { | |
674 | struct Scsi_Host *shost = class_to_shost(dev); | |
675 | struct bfad_im_port_s *im_port = | |
676 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 KG |
677 | struct bfad_s *bfad = im_port->bfad; |
678 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; | |
0a4b1fc0 | 679 | char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; |
75332a70 | 680 | int nports = 0; |
7725ccfd | 681 | |
a36c61f9 | 682 | bfa_get_adapter_model(&bfad->bfa, model); |
75332a70 | 683 | nports = bfa_get_nports(&bfad->bfa); |
a36c61f9 KG |
684 | if (!strcmp(model, "Brocade-425")) |
685 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
686 | "Brocade 4Gbps PCIe dual port FC HBA"); | |
687 | else if (!strcmp(model, "Brocade-825")) | |
688 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
689 | "Brocade 8Gbps PCIe dual port FC HBA"); | |
690 | else if (!strcmp(model, "Brocade-42B")) | |
691 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 692 | "Brocade 4Gbps PCIe dual port FC HBA for HP"); |
a36c61f9 KG |
693 | else if (!strcmp(model, "Brocade-82B")) |
694 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 695 | "Brocade 8Gbps PCIe dual port FC HBA for HP"); |
a36c61f9 KG |
696 | else if (!strcmp(model, "Brocade-1010")) |
697 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
698 | "Brocade 10Gbps single port CNA"); | |
699 | else if (!strcmp(model, "Brocade-1020")) | |
700 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
701 | "Brocade 10Gbps dual port CNA"); | |
702 | else if (!strcmp(model, "Brocade-1007")) | |
703 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 704 | "Brocade 10Gbps CNA for IBM Blade Center"); |
a36c61f9 KG |
705 | else if (!strcmp(model, "Brocade-415")) |
706 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
707 | "Brocade 4Gbps PCIe single port FC HBA"); | |
708 | else if (!strcmp(model, "Brocade-815")) | |
709 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
710 | "Brocade 8Gbps PCIe single port FC HBA"); | |
711 | else if (!strcmp(model, "Brocade-41B")) | |
712 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 713 | "Brocade 4Gbps PCIe single port FC HBA for HP"); |
a36c61f9 KG |
714 | else if (!strcmp(model, "Brocade-81B")) |
715 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 | 716 | "Brocade 8Gbps PCIe single port FC HBA for HP"); |
a36c61f9 KG |
717 | else if (!strcmp(model, "Brocade-804")) |
718 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
75332a70 KG |
719 | "Brocade 8Gbps FC HBA for HP Bladesystem C-class"); |
720 | else if (!strcmp(model, "Brocade-902") || | |
721 | !strcmp(model, "Brocade-1741")) | |
a36c61f9 | 722 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, |
75332a70 KG |
723 | "Brocade 10Gbps CNA for Dell M-Series Blade Servers"); |
724 | else if (strstr(model, "Brocade-1560")) { | |
725 | if (nports == 1) | |
726 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
727 | "Brocade 16Gbps PCIe single port FC HBA"); | |
728 | else | |
729 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
730 | "Brocade 16Gbps PCIe dual port FC HBA"); | |
731 | } else if (strstr(model, "Brocade-1710")) { | |
732 | if (nports == 1) | |
733 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
734 | "Brocade 10Gbps single port CNA"); | |
735 | else | |
736 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
737 | "Brocade 10Gbps dual port CNA"); | |
738 | } else if (strstr(model, "Brocade-1860")) { | |
739 | if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc)) | |
740 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
741 | "Brocade 10Gbps single port CNA"); | |
742 | else if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) | |
743 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
744 | "Brocade 16Gbps PCIe single port FC HBA"); | |
745 | else if (nports == 2 && bfa_ioc_is_cna(&bfad->bfa.ioc)) | |
746 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
747 | "Brocade 10Gbps dual port CNA"); | |
748 | else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc)) | |
749 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, | |
750 | "Brocade 16Gbps PCIe dual port FC HBA"); | |
751 | } else | |
a36c61f9 KG |
752 | snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, |
753 | "Invalid Model"); | |
754 | ||
0a4b1fc0 | 755 | return snprintf(buf, PAGE_SIZE, "%s\n", model_descr); |
7725ccfd JH |
756 | } |
757 | ||
758 | static ssize_t | |
759 | bfad_im_node_name_show(struct device *dev, struct device_attribute *attr, | |
760 | char *buf) | |
761 | { | |
762 | struct Scsi_Host *shost = class_to_shost(dev); | |
763 | struct bfad_im_port_s *im_port = | |
764 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
765 | struct bfad_port_s *port = im_port->port; | |
766 | u64 nwwn; | |
767 | ||
a36c61f9 | 768 | nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port); |
ba816ea8 | 769 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", cpu_to_be64(nwwn)); |
7725ccfd JH |
770 | } |
771 | ||
772 | static ssize_t | |
773 | bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, | |
774 | char *buf) | |
775 | { | |
776 | struct Scsi_Host *shost = class_to_shost(dev); | |
777 | struct bfad_im_port_s *im_port = | |
778 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 KG |
779 | struct bfad_s *bfad = im_port->bfad; |
780 | struct bfa_lport_attr_s port_attr; | |
781 | char symname[BFA_SYMNAME_MAXLEN]; | |
7725ccfd | 782 | |
a36c61f9 KG |
783 | bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); |
784 | strncpy(symname, port_attr.port_cfg.sym_name.symname, | |
785 | BFA_SYMNAME_MAXLEN); | |
786 | return snprintf(buf, PAGE_SIZE, "%s\n", symname); | |
7725ccfd JH |
787 | } |
788 | ||
789 | static ssize_t | |
790 | bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, | |
791 | char *buf) | |
792 | { | |
793 | struct Scsi_Host *shost = class_to_shost(dev); | |
794 | struct bfad_im_port_s *im_port = | |
795 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 796 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 797 | char hw_ver[BFA_VERSION_LEN]; |
7725ccfd | 798 | |
0a4b1fc0 KG |
799 | bfa_get_pci_chip_rev(&bfad->bfa, hw_ver); |
800 | return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver); | |
7725ccfd JH |
801 | } |
802 | ||
803 | static ssize_t | |
804 | bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, | |
805 | char *buf) | |
806 | { | |
807 | return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION); | |
808 | } | |
809 | ||
810 | static ssize_t | |
811 | bfad_im_optionrom_version_show(struct device *dev, | |
812 | struct device_attribute *attr, char *buf) | |
813 | { | |
814 | struct Scsi_Host *shost = class_to_shost(dev); | |
815 | struct bfad_im_port_s *im_port = | |
816 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 817 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 818 | char optrom_ver[BFA_VERSION_LEN]; |
7725ccfd | 819 | |
0a4b1fc0 KG |
820 | bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver); |
821 | return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver); | |
7725ccfd JH |
822 | } |
823 | ||
824 | static ssize_t | |
825 | bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr, | |
826 | char *buf) | |
827 | { | |
828 | struct Scsi_Host *shost = class_to_shost(dev); | |
829 | struct bfad_im_port_s *im_port = | |
830 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 831 | struct bfad_s *bfad = im_port->bfad; |
0a4b1fc0 | 832 | char fw_ver[BFA_VERSION_LEN]; |
7725ccfd | 833 | |
0a4b1fc0 KG |
834 | bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); |
835 | return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver); | |
7725ccfd JH |
836 | } |
837 | ||
838 | static ssize_t | |
839 | bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, | |
840 | char *buf) | |
841 | { | |
842 | struct Scsi_Host *shost = class_to_shost(dev); | |
843 | struct bfad_im_port_s *im_port = | |
844 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
a36c61f9 | 845 | struct bfad_s *bfad = im_port->bfad; |
7725ccfd | 846 | |
0a4b1fc0 | 847 | return snprintf(buf, PAGE_SIZE, "%d\n", |
a36c61f9 | 848 | bfa_get_nports(&bfad->bfa)); |
7725ccfd JH |
849 | } |
850 | ||
851 | static ssize_t | |
852 | bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, | |
853 | char *buf) | |
854 | { | |
855 | return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME); | |
856 | } | |
857 | ||
858 | static ssize_t | |
859 | bfad_im_num_of_discovered_ports_show(struct device *dev, | |
860 | struct device_attribute *attr, char *buf) | |
861 | { | |
862 | struct Scsi_Host *shost = class_to_shost(dev); | |
863 | struct bfad_im_port_s *im_port = | |
864 | (struct bfad_im_port_s *) shost->hostdata[0]; | |
865 | struct bfad_port_s *port = im_port->port; | |
866 | struct bfad_s *bfad = im_port->bfad; | |
867 | int nrports = 2048; | |
868 | wwn_t *rports = NULL; | |
869 | unsigned long flags; | |
870 | ||
871 | rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC); | |
872 | if (rports == NULL) | |
a36c61f9 | 873 | return snprintf(buf, PAGE_SIZE, "Failed\n"); |
7725ccfd JH |
874 | |
875 | spin_lock_irqsave(&bfad->bfad_lock, flags); | |
a36c61f9 | 876 | bfa_fcs_lport_get_rports(port->fcs_port, rports, &nrports); |
7725ccfd JH |
877 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
878 | kfree(rports); | |
879 | ||
880 | return snprintf(buf, PAGE_SIZE, "%d\n", nrports); | |
881 | } | |
882 | ||
883 | static DEVICE_ATTR(serial_number, S_IRUGO, | |
884 | bfad_im_serial_num_show, NULL); | |
885 | static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL); | |
886 | static DEVICE_ATTR(model_description, S_IRUGO, | |
887 | bfad_im_model_desc_show, NULL); | |
888 | static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL); | |
889 | static DEVICE_ATTR(symbolic_name, S_IRUGO, | |
890 | bfad_im_symbolic_name_show, NULL); | |
891 | static DEVICE_ATTR(hardware_version, S_IRUGO, | |
892 | bfad_im_hw_version_show, NULL); | |
893 | static DEVICE_ATTR(driver_version, S_IRUGO, | |
894 | bfad_im_drv_version_show, NULL); | |
895 | static DEVICE_ATTR(option_rom_version, S_IRUGO, | |
896 | bfad_im_optionrom_version_show, NULL); | |
897 | static DEVICE_ATTR(firmware_version, S_IRUGO, | |
898 | bfad_im_fw_version_show, NULL); | |
899 | static DEVICE_ATTR(number_of_ports, S_IRUGO, | |
900 | bfad_im_num_of_ports_show, NULL); | |
901 | static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL); | |
902 | static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO, | |
903 | bfad_im_num_of_discovered_ports_show, NULL); | |
904 | ||
905 | struct device_attribute *bfad_im_host_attrs[] = { | |
906 | &dev_attr_serial_number, | |
907 | &dev_attr_model, | |
908 | &dev_attr_model_description, | |
909 | &dev_attr_node_name, | |
910 | &dev_attr_symbolic_name, | |
911 | &dev_attr_hardware_version, | |
912 | &dev_attr_driver_version, | |
913 | &dev_attr_option_rom_version, | |
914 | &dev_attr_firmware_version, | |
915 | &dev_attr_number_of_ports, | |
916 | &dev_attr_driver_name, | |
917 | &dev_attr_number_of_discovered_ports, | |
918 | NULL, | |
919 | }; | |
920 | ||
921 | struct device_attribute *bfad_im_vport_attrs[] = { | |
a36c61f9 KG |
922 | &dev_attr_serial_number, |
923 | &dev_attr_model, | |
924 | &dev_attr_model_description, | |
925 | &dev_attr_node_name, | |
926 | &dev_attr_symbolic_name, | |
927 | &dev_attr_hardware_version, | |
928 | &dev_attr_driver_version, | |
929 | &dev_attr_option_rom_version, | |
930 | &dev_attr_firmware_version, | |
931 | &dev_attr_number_of_ports, | |
932 | &dev_attr_driver_name, | |
933 | &dev_attr_number_of_discovered_ports, | |
934 | NULL, | |
7725ccfd JH |
935 | }; |
936 | ||
937 |