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