Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[linux-2.6] / drivers / scsi / qla2xxx / qla_attr.c
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 }