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
13static ssize_t
14qla2x00_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
33static ssize_t
34qla2x00_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
72static 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
83static ssize_t
84qla2x00_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
103static ssize_t
104qla2x00_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
148static 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
159static ssize_t
160qla2x00_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
178static ssize_t
179qla2x00_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
197static 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
208static ssize_t
209qla2x00_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
278static 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
288static ssize_t
289qla2x00_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
307static ssize_t
308qla2x00_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
326static 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
337static ssize_t
338qla2x00_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
374static 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
384static 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
398void
399qla2x00_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
418void
419qla2x00_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
438static ssize_t
439qla2x00_drvr_version_show(struct class_device *cdev, char *buf)
440{
441	return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
442}
443
444static ssize_t
445qla2x00_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
454static ssize_t
455qla2x00_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
465static ssize_t
466qla2x00_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
472static ssize_t
473qla2x00_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
481static ssize_t
482qla2x00_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
488static ssize_t
489qla2x00_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
496static ssize_t
497qla2x00_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
506static ssize_t
507qla2x00_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
544static ssize_t
545qla2x00_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
561static ssize_t
562qla2x00_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
587static ssize_t
588qla2x00_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
595static ssize_t
596qla2x00_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
614static ssize_t
615qla2x00_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
627static ssize_t
628qla2x00_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
658static ssize_t
659qla2x00_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
667static ssize_t
668qla2x00_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
676static ssize_t
677qla2x00_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
685static ssize_t
686qla2x00_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
695static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,
696	NULL);
697static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
698static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
699static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL);
700static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL);
701static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL);
702static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL);
703static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL);
704static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL);
705static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show,
706    qla2x00_zio_store);
707static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show,
708    qla2x00_zio_timer_store);
709static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show,
710    qla2x00_beacon_store);
711static CLASS_DEVICE_ATTR(optrom_bios_version, S_IRUGO,
712    qla2x00_optrom_bios_version_show, NULL);
713static CLASS_DEVICE_ATTR(optrom_efi_version, S_IRUGO,
714    qla2x00_optrom_efi_version_show, NULL);
715static CLASS_DEVICE_ATTR(optrom_fcode_version, S_IRUGO,
716    qla2x00_optrom_fcode_version_show, NULL);
717static CLASS_DEVICE_ATTR(optrom_fw_version, S_IRUGO,
718    qla2x00_optrom_fw_version_show, NULL);
719
720struct 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
742static void
743qla2x00_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
751static void
752qla2x00_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
771static void
772qla2x00_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
794static void
795qla2x00_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
812static void
813qla2x00_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
830static void
831qla2x00_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
849static void
850qla2x00_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
858static void
859qla2x00_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
872static int
873qla2x00_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
881static struct fc_host_statistics *
882qla2x00_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;
915done:
916	return pfc_host_stat;
917}
918
919static void
920qla2x00_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
927static void
928qla2x00_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
935static void
936qla2x00_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
949static void
950qla2x00_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
962struct 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
1001void
1002qla2x00_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