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