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