xref: /linux/drivers/scsi/qla2xxx/qla_attr.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1 /*
2  * QLogic Fibre Channel HBA Driver
3  * Copyright (c)  2003-2005 QLogic Corporation
4  *
5  * See LICENSE.qla2xxx for copyright and licensing details.
6  */
7 #include "qla_def.h"
8 
9 #include <linux/vmalloc.h>
10 
11 /* SYSFS attributes --------------------------------------------------------- */
12 
13 static ssize_t
14 qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off,
15     size_t count)
16 {
17 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
18 	    struct device, kobj)));
19 	char *rbuf = (char *)ha->fw_dump;
20 
21 	if (ha->fw_dump_reading == 0)
22 		return 0;
23 	if (off > ha->fw_dump_len)
24                 return 0;
25 	if (off + count > ha->fw_dump_len)
26 		count = ha->fw_dump_len - off;
27 
28 	memcpy(buf, &rbuf[off], count);
29 
30 	return (count);
31 }
32 
33 static ssize_t
34 qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
35     size_t count)
36 {
37 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
38 	    struct device, kobj)));
39 	int reading;
40 
41 	if (off != 0)
42 		return (0);
43 
44 	reading = simple_strtol(buf, NULL, 10);
45 	switch (reading) {
46 	case 0:
47 		if (!ha->fw_dump_reading)
48 			break;
49 
50 		qla_printk(KERN_INFO, ha,
51 		    "Firmware dump cleared on (%ld).\n", ha->host_no);
52 
53 		ha->fw_dump_reading = 0;
54 		ha->fw_dumped = 0;
55 		break;
56 	case 1:
57 		if (ha->fw_dumped && !ha->fw_dump_reading) {
58 			ha->fw_dump_reading = 1;
59 
60 			qla_printk(KERN_INFO, ha,
61 			    "Raw firmware dump ready for read on (%ld).\n",
62 			    ha->host_no);
63 		}
64 		break;
65 	case 2:
66 		qla2x00_alloc_fw_dump(ha);
67 		break;
68 	}
69 	return (count);
70 }
71 
72 static struct bin_attribute sysfs_fw_dump_attr = {
73 	.attr = {
74 		.name = "fw_dump",
75 		.mode = S_IRUSR | S_IWUSR,
76 		.owner = THIS_MODULE,
77 	},
78 	.size = 0,
79 	.read = qla2x00_sysfs_read_fw_dump,
80 	.write = qla2x00_sysfs_write_fw_dump,
81 };
82 
83 static ssize_t
84 qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off,
85     size_t count)
86 {
87 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
88 	    struct device, kobj)));
89 	unsigned long	flags;
90 
91 	if (!capable(CAP_SYS_ADMIN) || off != 0)
92 		return 0;
93 
94 	/* Read NVRAM. */
95 	spin_lock_irqsave(&ha->hardware_lock, flags);
96 	ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->nvram_base,
97 	    ha->nvram_size);
98 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
99 
100 	return ha->nvram_size;
101 }
102 
103 static ssize_t
104 qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off,
105     size_t count)
106 {
107 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
108 	    struct device, kobj)));
109 	unsigned long	flags;
110 	uint16_t	cnt;
111 
112 	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
113 		return 0;
114 
115 	/* Checksum NVRAM. */
116 	if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
117 		uint32_t *iter;
118 		uint32_t chksum;
119 
120 		iter = (uint32_t *)buf;
121 		chksum = 0;
122 		for (cnt = 0; cnt < ((count >> 2) - 1); cnt++)
123 			chksum += le32_to_cpu(*iter++);
124 		chksum = ~chksum + 1;
125 		*iter = cpu_to_le32(chksum);
126 	} else {
127 		uint8_t *iter;
128 		uint8_t chksum;
129 
130 		iter = (uint8_t *)buf;
131 		chksum = 0;
132 		for (cnt = 0; cnt < count - 1; cnt++)
133 			chksum += *iter++;
134 		chksum = ~chksum + 1;
135 		*iter = chksum;
136 	}
137 
138 	/* Write NVRAM. */
139 	spin_lock_irqsave(&ha->hardware_lock, flags);
140 	ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
141 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
142 
143 	set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
144 
145 	return (count);
146 }
147 
148 static struct bin_attribute sysfs_nvram_attr = {
149 	.attr = {
150 		.name = "nvram",
151 		.mode = S_IRUSR | S_IWUSR,
152 		.owner = THIS_MODULE,
153 	},
154 	.size = 512,
155 	.read = qla2x00_sysfs_read_nvram,
156 	.write = qla2x00_sysfs_write_nvram,
157 };
158 
159 static ssize_t
160 qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off,
161     size_t count)
162 {
163 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
164 	    struct device, kobj)));
165 
166 	if (ha->optrom_state != QLA_SREADING)
167 		return 0;
168 	if (off > ha->optrom_size)
169 		return 0;
170 	if (off + count > ha->optrom_size)
171 		count = ha->optrom_size - off;
172 
173 	memcpy(buf, &ha->optrom_buffer[off], count);
174 
175 	return count;
176 }
177 
178 static ssize_t
179 qla2x00_sysfs_write_optrom(struct kobject *kobj, char *buf, loff_t off,
180     size_t count)
181 {
182 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
183 	    struct device, kobj)));
184 
185 	if (ha->optrom_state != QLA_SWRITING)
186 		return -EINVAL;
187 	if (off > ha->optrom_size)
188 		return -ERANGE;
189 	if (off + count > ha->optrom_size)
190 		count = ha->optrom_size - off;
191 
192 	memcpy(&ha->optrom_buffer[off], buf, count);
193 
194 	return count;
195 }
196 
197 static struct bin_attribute sysfs_optrom_attr = {
198 	.attr = {
199 		.name = "optrom",
200 		.mode = S_IRUSR | S_IWUSR,
201 		.owner = THIS_MODULE,
202 	},
203 	.size = OPTROM_SIZE_24XX,
204 	.read = qla2x00_sysfs_read_optrom,
205 	.write = qla2x00_sysfs_write_optrom,
206 };
207 
208 static ssize_t
209 qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, char *buf, loff_t off,
210     size_t count)
211 {
212 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
213 	    struct device, kobj)));
214 	int val;
215 
216 	if (off)
217 		return 0;
218 
219 	if (sscanf(buf, "%d", &val) != 1)
220 		return -EINVAL;
221 
222 	switch (val) {
223 	case 0:
224 		if (ha->optrom_state != QLA_SREADING &&
225 		    ha->optrom_state != QLA_SWRITING)
226 			break;
227 
228 		ha->optrom_state = QLA_SWAITING;
229 		vfree(ha->optrom_buffer);
230 		ha->optrom_buffer = NULL;
231 		break;
232 	case 1:
233 		if (ha->optrom_state != QLA_SWAITING)
234 			break;
235 
236 		ha->optrom_state = QLA_SREADING;
237 		ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size);
238 		if (ha->optrom_buffer == NULL) {
239 			qla_printk(KERN_WARNING, ha,
240 			    "Unable to allocate memory for optrom retrieval "
241 			    "(%x).\n", ha->optrom_size);
242 
243 			ha->optrom_state = QLA_SWAITING;
244 			return count;
245 		}
246 
247 		memset(ha->optrom_buffer, 0, ha->optrom_size);
248 		ha->isp_ops.read_optrom(ha, ha->optrom_buffer, 0,
249 		    ha->optrom_size);
250 		break;
251 	case 2:
252 		if (ha->optrom_state != QLA_SWAITING)
253 			break;
254 
255 		ha->optrom_state = QLA_SWRITING;
256 		ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size);
257 		if (ha->optrom_buffer == NULL) {
258 			qla_printk(KERN_WARNING, ha,
259 			    "Unable to allocate memory for optrom update "
260 			    "(%x).\n", ha->optrom_size);
261 
262 			ha->optrom_state = QLA_SWAITING;
263 			return count;
264 		}
265 		memset(ha->optrom_buffer, 0, ha->optrom_size);
266 		break;
267 	case 3:
268 		if (ha->optrom_state != QLA_SWRITING)
269 			break;
270 
271 		ha->isp_ops.write_optrom(ha, ha->optrom_buffer, 0,
272 		    ha->optrom_size);
273 		break;
274 	}
275 	return count;
276 }
277 
278 static struct bin_attribute sysfs_optrom_ctl_attr = {
279 	.attr = {
280 		.name = "optrom_ctl",
281 		.mode = S_IWUSR,
282 		.owner = THIS_MODULE,
283 	},
284 	.size = 0,
285 	.write = qla2x00_sysfs_write_optrom_ctl,
286 };
287 
288 static ssize_t
289 qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off,
290     size_t count)
291 {
292 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
293 	    struct device, kobj)));
294 	unsigned long flags;
295 
296 	if (!capable(CAP_SYS_ADMIN) || off != 0)
297 		return 0;
298 
299 	/* Read NVRAM. */
300 	spin_lock_irqsave(&ha->hardware_lock, flags);
301 	ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size);
302 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
303 
304 	return ha->vpd_size;
305 }
306 
307 static ssize_t
308 qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off,
309     size_t count)
310 {
311 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
312 	    struct device, kobj)));
313 	unsigned long flags;
314 
315 	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
316 		return 0;
317 
318 	/* Write NVRAM. */
319 	spin_lock_irqsave(&ha->hardware_lock, flags);
320 	ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
321 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
322 
323 	return count;
324 }
325 
326 static struct bin_attribute sysfs_vpd_attr = {
327 	.attr = {
328 		.name = "vpd",
329 		.mode = S_IRUSR | S_IWUSR,
330 		.owner = THIS_MODULE,
331 	},
332 	.size = 0,
333 	.read = qla2x00_sysfs_read_vpd,
334 	.write = qla2x00_sysfs_write_vpd,
335 };
336 
337 static ssize_t
338 qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off,
339     size_t count)
340 {
341 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
342 	    struct device, kobj)));
343 	uint16_t iter, addr, offset;
344 	int rval;
345 
346 	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2)
347 		return 0;
348 
349 	addr = 0xa0;
350 	for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE;
351 	    iter++, offset += SFP_BLOCK_SIZE) {
352 		if (iter == 4) {
353 			/* Skip to next device address. */
354 			addr = 0xa2;
355 			offset = 0;
356 		}
357 
358 		rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset,
359 		    SFP_BLOCK_SIZE);
360 		if (rval != QLA_SUCCESS) {
361 			qla_printk(KERN_WARNING, ha,
362 			    "Unable to read SFP data (%x/%x/%x).\n", rval,
363 			    addr, offset);
364 			count = 0;
365 			break;
366 		}
367 		memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE);
368 		buf += SFP_BLOCK_SIZE;
369 	}
370 
371 	return count;
372 }
373 
374 static struct bin_attribute sysfs_sfp_attr = {
375 	.attr = {
376 		.name = "sfp",
377 		.mode = S_IRUSR | S_IWUSR,
378 		.owner = THIS_MODULE,
379 	},
380 	.size = SFP_DEV_SIZE * 2,
381 	.read = qla2x00_sysfs_read_sfp,
382 };
383 
384 static struct sysfs_entry {
385 	char *name;
386 	struct bin_attribute *attr;
387 	int is4GBp_only;
388 } bin_file_entries[] = {
389 	{ "fw_dump", &sysfs_fw_dump_attr, },
390 	{ "nvram", &sysfs_nvram_attr, },
391 	{ "optrom", &sysfs_optrom_attr, },
392 	{ "optrom_ctl", &sysfs_optrom_ctl_attr, },
393 	{ "vpd", &sysfs_vpd_attr, 1 },
394 	{ "sfp", &sysfs_sfp_attr, 1 },
395 	{ NULL },
396 };
397 
398 void
399 qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
400 {
401 	struct Scsi_Host *host = ha->host;
402 	struct sysfs_entry *iter;
403 	int ret;
404 
405 	for (iter = bin_file_entries; iter->name; iter++) {
406 		if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)))
407 			continue;
408 
409 		ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
410 		    iter->attr);
411 		if (ret)
412 			qla_printk(KERN_INFO, ha,
413 			    "Unable to create sysfs %s binary attribute "
414 			    "(%d).\n", iter->name, ret);
415 	}
416 }
417 
418 void
419 qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
420 {
421 	struct Scsi_Host *host = ha->host;
422 	struct sysfs_entry *iter;
423 
424 	for (iter = bin_file_entries; iter->name; iter++) {
425 		if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)))
426 			continue;
427 
428 		sysfs_remove_bin_file(&host->shost_gendev.kobj,
429 		    iter->attr);
430 	}
431 
432 	if (ha->beacon_blink_led == 1)
433 		ha->isp_ops.beacon_off(ha);
434 }
435 
436 /* Scsi_Host attributes. */
437 
438 static ssize_t
439 qla2x00_drvr_version_show(struct class_device *cdev, char *buf)
440 {
441 	return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
442 }
443 
444 static ssize_t
445 qla2x00_fw_version_show(struct class_device *cdev, char *buf)
446 {
447 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
448 	char fw_str[30];
449 
450 	return snprintf(buf, PAGE_SIZE, "%s\n",
451 	    ha->isp_ops.fw_version_str(ha, fw_str));
452 }
453 
454 static ssize_t
455 qla2x00_serial_num_show(struct class_device *cdev, char *buf)
456 {
457 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
458 	uint32_t sn;
459 
460 	sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
461 	return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,
462 	    sn % 100000);
463 }
464 
465 static ssize_t
466 qla2x00_isp_name_show(struct class_device *cdev, char *buf)
467 {
468 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
469 	return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device);
470 }
471 
472 static ssize_t
473 qla2x00_isp_id_show(struct class_device *cdev, char *buf)
474 {
475 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
476 	return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
477 	    ha->product_id[0], ha->product_id[1], ha->product_id[2],
478 	    ha->product_id[3]);
479 }
480 
481 static ssize_t
482 qla2x00_model_name_show(struct class_device *cdev, char *buf)
483 {
484 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
485 	return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number);
486 }
487 
488 static ssize_t
489 qla2x00_model_desc_show(struct class_device *cdev, char *buf)
490 {
491 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
492 	return snprintf(buf, PAGE_SIZE, "%s\n",
493 	    ha->model_desc ? ha->model_desc: "");
494 }
495 
496 static ssize_t
497 qla2x00_pci_info_show(struct class_device *cdev, char *buf)
498 {
499 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
500 	char pci_info[30];
501 
502 	return snprintf(buf, PAGE_SIZE, "%s\n",
503 	    ha->isp_ops.pci_info_str(ha, pci_info));
504 }
505 
506 static ssize_t
507 qla2x00_state_show(struct class_device *cdev, char *buf)
508 {
509 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
510 	int len = 0;
511 
512 	if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
513 	    atomic_read(&ha->loop_state) == LOOP_DEAD)
514 		len = snprintf(buf, PAGE_SIZE, "Link Down\n");
515 	else if (atomic_read(&ha->loop_state) != LOOP_READY ||
516 	    test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||
517 	    test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags))
518 		len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
519 	else {
520 		len = snprintf(buf, PAGE_SIZE, "Link Up - ");
521 
522 		switch (ha->current_topology) {
523 		case ISP_CFG_NL:
524 			len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
525 			break;
526 		case ISP_CFG_FL:
527 			len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n");
528 			break;
529 		case ISP_CFG_N:
530 			len += snprintf(buf + len, PAGE_SIZE-len,
531 			    "N_Port to N_Port\n");
532 			break;
533 		case ISP_CFG_F:
534 			len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n");
535 			break;
536 		default:
537 			len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
538 			break;
539 		}
540 	}
541 	return len;
542 }
543 
544 static ssize_t
545 qla2x00_zio_show(struct class_device *cdev, char *buf)
546 {
547 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
548 	int len = 0;
549 
550 	switch (ha->zio_mode) {
551 	case QLA_ZIO_MODE_6:
552 		len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");
553 		break;
554 	case QLA_ZIO_DISABLED:
555 		len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
556 		break;
557 	}
558 	return len;
559 }
560 
561 static ssize_t
562 qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count)
563 {
564 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
565 	int val = 0;
566 	uint16_t zio_mode;
567 
568 	if (!IS_ZIO_SUPPORTED(ha))
569 		return -ENOTSUPP;
570 
571 	if (sscanf(buf, "%d", &val) != 1)
572 		return -EINVAL;
573 
574 	if (val)
575 		zio_mode = QLA_ZIO_MODE_6;
576 	else
577 		zio_mode = QLA_ZIO_DISABLED;
578 
579 	/* Update per-hba values and queue a reset. */
580 	if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) {
581 		ha->zio_mode = zio_mode;
582 		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
583 	}
584 	return strlen(buf);
585 }
586 
587 static ssize_t
588 qla2x00_zio_timer_show(struct class_device *cdev, char *buf)
589 {
590 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
591 
592 	return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100);
593 }
594 
595 static ssize_t
596 qla2x00_zio_timer_store(struct class_device *cdev, const char *buf,
597     size_t count)
598 {
599 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
600 	int val = 0;
601 	uint16_t zio_timer;
602 
603 	if (sscanf(buf, "%d", &val) != 1)
604 		return -EINVAL;
605 	if (val > 25500 || val < 100)
606 		return -ERANGE;
607 
608 	zio_timer = (uint16_t)(val / 100);
609 	ha->zio_timer = zio_timer;
610 
611 	return strlen(buf);
612 }
613 
614 static ssize_t
615 qla2x00_beacon_show(struct class_device *cdev, char *buf)
616 {
617 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
618 	int len = 0;
619 
620 	if (ha->beacon_blink_led)
621 		len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n");
622 	else
623 		len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
624 	return len;
625 }
626 
627 static ssize_t
628 qla2x00_beacon_store(struct class_device *cdev, const char *buf,
629     size_t count)
630 {
631 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
632 	int val = 0;
633 	int rval;
634 
635 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
636 		return -EPERM;
637 
638 	if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) {
639 		qla_printk(KERN_WARNING, ha,
640 		    "Abort ISP active -- ignoring beacon request.\n");
641 		return -EBUSY;
642 	}
643 
644 	if (sscanf(buf, "%d", &val) != 1)
645 		return -EINVAL;
646 
647 	if (val)
648 		rval = ha->isp_ops.beacon_on(ha);
649 	else
650 		rval = ha->isp_ops.beacon_off(ha);
651 
652 	if (rval != QLA_SUCCESS)
653 		count = 0;
654 
655 	return count;
656 }
657 
658 static ssize_t
659 qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf)
660 {
661 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
662 
663 	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1],
664 	    ha->bios_revision[0]);
665 }
666 
667 static ssize_t
668 qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf)
669 {
670 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
671 
672 	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1],
673 	    ha->efi_revision[0]);
674 }
675 
676 static ssize_t
677 qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf)
678 {
679 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
680 
681 	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1],
682 	    ha->fcode_revision[0]);
683 }
684 
685 static ssize_t
686 qla2x00_optrom_fw_version_show(struct class_device *cdev, char *buf)
687 {
688 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
689 
690 	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n",
691 	    ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2],
692 	    ha->fw_revision[3]);
693 }
694 
695 static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,
696 	NULL);
697 static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
698 static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
699 static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL);
700 static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL);
701 static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL);
702 static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL);
703 static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL);
704 static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL);
705 static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show,
706     qla2x00_zio_store);
707 static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show,
708     qla2x00_zio_timer_store);
709 static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show,
710     qla2x00_beacon_store);
711 static CLASS_DEVICE_ATTR(optrom_bios_version, S_IRUGO,
712     qla2x00_optrom_bios_version_show, NULL);
713 static CLASS_DEVICE_ATTR(optrom_efi_version, S_IRUGO,
714     qla2x00_optrom_efi_version_show, NULL);
715 static CLASS_DEVICE_ATTR(optrom_fcode_version, S_IRUGO,
716     qla2x00_optrom_fcode_version_show, NULL);
717 static CLASS_DEVICE_ATTR(optrom_fw_version, S_IRUGO,
718     qla2x00_optrom_fw_version_show, NULL);
719 
720 struct class_device_attribute *qla2x00_host_attrs[] = {
721 	&class_device_attr_driver_version,
722 	&class_device_attr_fw_version,
723 	&class_device_attr_serial_num,
724 	&class_device_attr_isp_name,
725 	&class_device_attr_isp_id,
726 	&class_device_attr_model_name,
727 	&class_device_attr_model_desc,
728 	&class_device_attr_pci_info,
729 	&class_device_attr_state,
730 	&class_device_attr_zio,
731 	&class_device_attr_zio_timer,
732 	&class_device_attr_beacon,
733 	&class_device_attr_optrom_bios_version,
734 	&class_device_attr_optrom_efi_version,
735 	&class_device_attr_optrom_fcode_version,
736 	&class_device_attr_optrom_fw_version,
737 	NULL,
738 };
739 
740 /* Host attributes. */
741 
742 static void
743 qla2x00_get_host_port_id(struct Scsi_Host *shost)
744 {
745 	scsi_qla_host_t *ha = to_qla_host(shost);
746 
747 	fc_host_port_id(shost) = ha->d_id.b.domain << 16 |
748 	    ha->d_id.b.area << 8 | ha->d_id.b.al_pa;
749 }
750 
751 static void
752 qla2x00_get_host_speed(struct Scsi_Host *shost)
753 {
754 	scsi_qla_host_t *ha = to_qla_host(shost);
755 	uint32_t speed = 0;
756 
757 	switch (ha->link_data_rate) {
758 	case PORT_SPEED_1GB:
759 		speed = 1;
760 		break;
761 	case PORT_SPEED_2GB:
762 		speed = 2;
763 		break;
764 	case PORT_SPEED_4GB:
765 		speed = 4;
766 		break;
767 	}
768 	fc_host_speed(shost) = speed;
769 }
770 
771 static void
772 qla2x00_get_host_port_type(struct Scsi_Host *shost)
773 {
774 	scsi_qla_host_t *ha = to_qla_host(shost);
775 	uint32_t port_type = FC_PORTTYPE_UNKNOWN;
776 
777 	switch (ha->current_topology) {
778 	case ISP_CFG_NL:
779 		port_type = FC_PORTTYPE_LPORT;
780 		break;
781 	case ISP_CFG_FL:
782 		port_type = FC_PORTTYPE_NLPORT;
783 		break;
784 	case ISP_CFG_N:
785 		port_type = FC_PORTTYPE_PTP;
786 		break;
787 	case ISP_CFG_F:
788 		port_type = FC_PORTTYPE_NPORT;
789 		break;
790 	}
791 	fc_host_port_type(shost) = port_type;
792 }
793 
794 static void
795 qla2x00_get_starget_node_name(struct scsi_target *starget)
796 {
797 	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
798 	scsi_qla_host_t *ha = to_qla_host(host);
799 	fc_port_t *fcport;
800 	u64 node_name = 0;
801 
802 	list_for_each_entry(fcport, &ha->fcports, list) {
803 		if (starget->id == fcport->os_target_id) {
804 			node_name = wwn_to_u64(fcport->node_name);
805 			break;
806 		}
807 	}
808 
809 	fc_starget_node_name(starget) = node_name;
810 }
811 
812 static void
813 qla2x00_get_starget_port_name(struct scsi_target *starget)
814 {
815 	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
816 	scsi_qla_host_t *ha = to_qla_host(host);
817 	fc_port_t *fcport;
818 	u64 port_name = 0;
819 
820 	list_for_each_entry(fcport, &ha->fcports, list) {
821 		if (starget->id == fcport->os_target_id) {
822 			port_name = wwn_to_u64(fcport->port_name);
823 			break;
824 		}
825 	}
826 
827 	fc_starget_port_name(starget) = port_name;
828 }
829 
830 static void
831 qla2x00_get_starget_port_id(struct scsi_target *starget)
832 {
833 	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
834 	scsi_qla_host_t *ha = to_qla_host(host);
835 	fc_port_t *fcport;
836 	uint32_t port_id = ~0U;
837 
838 	list_for_each_entry(fcport, &ha->fcports, list) {
839 		if (starget->id == fcport->os_target_id) {
840 			port_id = fcport->d_id.b.domain << 16 |
841 			    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
842 			break;
843 		}
844 	}
845 
846 	fc_starget_port_id(starget) = port_id;
847 }
848 
849 static void
850 qla2x00_get_rport_loss_tmo(struct fc_rport *rport)
851 {
852 	struct Scsi_Host *host = rport_to_shost(rport);
853 	scsi_qla_host_t *ha = to_qla_host(host);
854 
855 	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
856 }
857 
858 static void
859 qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
860 {
861 	struct Scsi_Host *host = rport_to_shost(rport);
862 	scsi_qla_host_t *ha = to_qla_host(host);
863 
864 	if (timeout)
865 		ha->port_down_retry_count = timeout;
866 	else
867 		ha->port_down_retry_count = 1;
868 
869 	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
870 }
871 
872 static int
873 qla2x00_issue_lip(struct Scsi_Host *shost)
874 {
875 	scsi_qla_host_t *ha = to_qla_host(shost);
876 
877 	set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags);
878 	return 0;
879 }
880 
881 static struct fc_host_statistics *
882 qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
883 {
884 	scsi_qla_host_t *ha = to_qla_host(shost);
885 	int rval;
886 	uint16_t mb_stat[1];
887 	link_stat_t stat_buf;
888 	struct fc_host_statistics *pfc_host_stat;
889 
890 	rval = QLA_FUNCTION_FAILED;
891 	pfc_host_stat = &ha->fc_host_stat;
892 	memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics));
893 
894 	if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
895 		rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf,
896 		    sizeof(stat_buf) / 4, mb_stat);
897 	} else if (atomic_read(&ha->loop_state) == LOOP_READY &&
898 		    !test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) &&
899 		    !test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) &&
900 		    !ha->dpc_active) {
901 		/* Must be in a 'READY' state for statistics retrieval. */
902 		rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf,
903 		    mb_stat);
904 	}
905 
906 	if (rval != QLA_SUCCESS)
907 		goto done;
908 
909 	pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt;
910 	pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt;
911 	pfc_host_stat->loss_of_signal_count = stat_buf.loss_sig_cnt;
912 	pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt;
913 	pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt;
914 	pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt;
915 done:
916 	return pfc_host_stat;
917 }
918 
919 static void
920 qla2x00_get_host_symbolic_name(struct Scsi_Host *shost)
921 {
922 	scsi_qla_host_t *ha = to_qla_host(shost);
923 
924 	qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost));
925 }
926 
927 static void
928 qla2x00_set_host_system_hostname(struct Scsi_Host *shost)
929 {
930 	scsi_qla_host_t *ha = to_qla_host(shost);
931 
932 	set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
933 }
934 
935 static void
936 qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
937 {
938 	scsi_qla_host_t *ha = to_qla_host(shost);
939 	u64 node_name;
940 
941 	if (ha->device_flags & SWITCH_FOUND)
942 		node_name = wwn_to_u64(ha->fabric_node_name);
943 	else
944 		node_name = wwn_to_u64(ha->node_name);
945 
946 	fc_host_fabric_name(shost) = node_name;
947 }
948 
949 static void
950 qla2x00_get_host_port_state(struct Scsi_Host *shost)
951 {
952 	scsi_qla_host_t *ha = to_qla_host(shost);
953 
954 	if (!ha->flags.online)
955 		fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
956 	else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT)
957 		fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
958 	else
959 		fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
960 }
961 
962 struct fc_function_template qla2xxx_transport_functions = {
963 
964 	.show_host_node_name = 1,
965 	.show_host_port_name = 1,
966 	.show_host_supported_classes = 1,
967 
968 	.get_host_port_id = qla2x00_get_host_port_id,
969 	.show_host_port_id = 1,
970 	.get_host_speed = qla2x00_get_host_speed,
971 	.show_host_speed = 1,
972 	.get_host_port_type = qla2x00_get_host_port_type,
973 	.show_host_port_type = 1,
974 	.get_host_symbolic_name = qla2x00_get_host_symbolic_name,
975 	.show_host_symbolic_name = 1,
976 	.set_host_system_hostname = qla2x00_set_host_system_hostname,
977 	.show_host_system_hostname = 1,
978 	.get_host_fabric_name = qla2x00_get_host_fabric_name,
979 	.show_host_fabric_name = 1,
980 	.get_host_port_state = qla2x00_get_host_port_state,
981 	.show_host_port_state = 1,
982 
983 	.dd_fcrport_size = sizeof(struct fc_port *),
984 	.show_rport_supported_classes = 1,
985 
986 	.get_starget_node_name = qla2x00_get_starget_node_name,
987 	.show_starget_node_name = 1,
988 	.get_starget_port_name = qla2x00_get_starget_port_name,
989 	.show_starget_port_name = 1,
990 	.get_starget_port_id  = qla2x00_get_starget_port_id,
991 	.show_starget_port_id = 1,
992 
993 	.get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
994 	.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
995 	.show_rport_dev_loss_tmo = 1,
996 
997 	.issue_fc_host_lip = qla2x00_issue_lip,
998 	.get_fc_host_stats = qla2x00_get_fc_host_stats,
999 };
1000 
1001 void
1002 qla2x00_init_host_attr(scsi_qla_host_t *ha)
1003 {
1004 	fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
1005 	fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
1006 	fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
1007 }
1008