Message ID | 20200831171844.635729-1-tyreld@linux.ibm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | scsi: ibmvfc: interface updates for future FPIN and MQ support | expand |
Hi Tyrel, I love your patch! Yet something to improve: [auto build test ERROR on powerpc/next] [also build test ERROR on mkp-scsi/for-next scsi/for-next v5.9-rc3 next-20200828] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Tyrel-Datwyler/scsi-ibmvfc-interface-updates-for-future-FPIN-and-MQ-support/20200901-012005 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next config: powerpc-defconfig (attached as .config) compiler: powerpc64-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): In file included from drivers/scsi/ibmvscsi/ibmvfc.c:32: >> drivers/scsi/ibmvscsi/ibmvfc.h:500:13: error: expected ':', ',', ';', '}' or '__attribute__' before 'nvmeof_vas_channels' 500 | __be32 num nvmeof_vas_channels; | ^~~~~~~~~~~~~~~~~~~ >> drivers/scsi/ibmvscsi/ibmvfc.h:506:17: error: expected declaration specifiers or '...' before '(' token 506 | }__attrribute__((packed, aligned (8))); | ^ >> drivers/scsi/ibmvscsi/ibmvfc.h:526:28: error: field 'common' has incomplete type 526 | struct ibmvfc_madd_common common; | ^~~~~~ >> drivers/scsi/ibmvscsi/ibmvfc.h:627:2: error: expected ':', ',', ';', '}' or '__attribute__' before 'u8' 627 | u8 pad; | ^~ In file included from include/linux/byteorder/big_endian.h:5, from arch/powerpc/include/uapi/asm/byteorder.h:14, from include/asm-generic/bitops/le.h:6, from arch/powerpc/include/asm/bitops.h:246, from include/linux/bitops.h:29, from include/linux/kernel.h:12, from include/linux/list.h:9, from include/linux/module.h:12, from drivers/scsi/ibmvscsi/ibmvfc.c:10: drivers/scsi/ibmvscsi/ibmvfc.c: In function 'ibmvfc_handle_async': >> drivers/scsi/ibmvscsi/ibmvfc.c:2665:75: error: 'struct ibmvfc_async_crq' has no member named 'event' 2665 | const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(be64_to_cpu(crq->event)); | ^~ include/uapi/linux/byteorder/big_endian.h:38:51: note: in definition of macro '__be64_to_cpu' 38 | #define __be64_to_cpu(x) ((__force __u64)(__be64)(x)) | ^ drivers/scsi/ibmvscsi/ibmvfc.c:2665:60: note: in expansion of macro 'be64_to_cpu' 2665 | const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(be64_to_cpu(crq->event)); | ^~~~~~~~~~~ >> drivers/scsi/ibmvscsi/ibmvfc.c:2669:57: error: 'struct ibmvfc_async_crq' has no member named 'scsi_id' 2669 | " node_name: %llx%s\n", desc->desc, be64_to_cpu(crq->scsi_id), | ^~ include/uapi/linux/byteorder/big_endian.h:38:51: note: in definition of macro '__be64_to_cpu' 38 | #define __be64_to_cpu(x) ((__force __u64)(__be64)(x)) | ^ drivers/scsi/ibmvscsi/ibmvfc.h:818:4: note: in expansion of macro 'dev_err' 818 | dev_err((vhost)->dev, ##__VA_ARGS__); \ | ^~~~~~~ drivers/scsi/ibmvscsi/ibmvfc.c:2668:2: note: in expansion of macro 'ibmvfc_log' 2668 | ibmvfc_log(vhost, desc->log_level, "%s event received. scsi_id: %llx, wwpn: %llx," | ^~~~~~~~~~ >> drivers/scsi/ibmvscsi/ibmvfc.c:2670:21: error: 'struct ibmvfc_async_crq' has no member named 'wwpn' 2670 | be64_to_cpu(crq->wwpn), be64_to_cpu(crq->node_name), | ^~ include/uapi/linux/byteorder/big_endian.h:38:51: note: in definition of macro '__be64_to_cpu' 38 | #define __be64_to_cpu(x) ((__force __u64)(__be64)(x)) | ^ drivers/scsi/ibmvscsi/ibmvfc.h:818:4: note: in expansion of macro 'dev_err' 818 | dev_err((vhost)->dev, ##__VA_ARGS__); \ | ^~~~~~~ drivers/scsi/ibmvscsi/ibmvfc.c:2668:2: note: in expansion of macro 'ibmvfc_log' 2668 | ibmvfc_log(vhost, desc->log_level, "%s event received. scsi_id: %llx, wwpn: %llx," | ^~~~~~~~~~ >> drivers/scsi/ibmvscsi/ibmvfc.c:2670:45: error: 'struct ibmvfc_async_crq' has no member named 'node_name' 2670 | be64_to_cpu(crq->wwpn), be64_to_cpu(crq->node_name), | ^~ include/uapi/linux/byteorder/big_endian.h:38:51: note: in definition of macro '__be64_to_cpu' 38 | #define __be64_to_cpu(x) ((__force __u64)(__be64)(x)) | ^ drivers/scsi/ibmvscsi/ibmvfc.h:818:4: note: in expansion of macro 'dev_err' 818 | dev_err((vhost)->dev, ##__VA_ARGS__); \ | ^~~~~~~ drivers/scsi/ibmvscsi/ibmvfc.c:2668:2: note: in expansion of macro 'ibmvfc_log' 2668 | ibmvfc_log(vhost, desc->log_level, "%s event received. scsi_id: %llx, wwpn: %llx," | ^~~~~~~~~~ drivers/scsi/ibmvscsi/ibmvfc.c:2673:25: error: 'struct ibmvfc_async_crq' has no member named 'event' 2673 | switch (be64_to_cpu(crq->event)) { | ^~ include/uapi/linux/byteorder/big_endian.h:38:51: note: in definition of macro '__be64_to_cpu' 38 | #define __be64_to_cpu(x) ((__force __u64)(__be64)(x)) | ^ drivers/scsi/ibmvscsi/ibmvfc.c:2673:10: note: in expansion of macro 'be64_to_cpu' 2673 | switch (be64_to_cpu(crq->event)) { | ^~~~~~~~~~~ drivers/scsi/ibmvscsi/ibmvfc.c:2714:12: error: 'struct ibmvfc_async_crq' has no member named 'scsi_id' 2714 | if (!crq->scsi_id && !crq->wwpn && !crq->node_name) | ^~ drivers/scsi/ibmvscsi/ibmvfc.c:2714:29: error: 'struct ibmvfc_async_crq' has no member named 'wwpn' 2714 | if (!crq->scsi_id && !crq->wwpn && !crq->node_name) | ^~ drivers/scsi/ibmvscsi/ibmvfc.c:2714:43: error: 'struct ibmvfc_async_crq' has no member named 'node_name' 2714 | if (!crq->scsi_id && !crq->wwpn && !crq->node_name) | ^~ drivers/scsi/ibmvscsi/ibmvfc.c:2716:11: error: 'struct ibmvfc_async_crq' has no member named 'scsi_id' 2716 | if (crq->scsi_id && cpu_to_be64(tgt->scsi_id) != crq->scsi_id) | ^~ drivers/scsi/ibmvscsi/ibmvfc.c:2716:56: error: 'struct ibmvfc_async_crq' has no member named 'scsi_id' 2716 | if (crq->scsi_id && cpu_to_be64(tgt->scsi_id) != crq->scsi_id) | ^~ drivers/scsi/ibmvscsi/ibmvfc.c:2718:11: error: 'struct ibmvfc_async_crq' has no member named 'wwpn' 2718 | if (crq->wwpn && cpu_to_be64(tgt->ids.port_name) != crq->wwpn) | ^~ drivers/scsi/ibmvscsi/ibmvfc.c:2718:59: error: 'struct ibmvfc_async_crq' has no member named 'wwpn' 2718 | if (crq->wwpn && cpu_to_be64(tgt->ids.port_name) != crq->wwpn) | ^~ drivers/scsi/ibmvscsi/ibmvfc.c:2720:11: error: 'struct ibmvfc_async_crq' has no member named 'node_name' 2720 | if (crq->node_name && cpu_to_be64(tgt->ids.node_name) != crq->node_name) | ^~ drivers/scsi/ibmvscsi/ibmvfc.c:2720:64: error: 'struct ibmvfc_async_crq' has no member named 'node_name' 2720 | if (crq->node_name && cpu_to_be64(tgt->ids.node_name) != crq->node_name) | ^~ In file included from include/linux/byteorder/big_endian.h:5, from arch/powerpc/include/uapi/asm/byteorder.h:14, from include/asm-generic/bitops/le.h:6, from arch/powerpc/include/asm/bitops.h:246, from include/linux/bitops.h:29, from include/linux/kernel.h:12, from include/linux/list.h:9, from include/linux/module.h:12, from drivers/scsi/ibmvscsi/ibmvfc.c:10: drivers/scsi/ibmvscsi/ibmvfc.c:2722:42: error: 'struct ibmvfc_async_crq' has no member named 'event' 2722 | if (tgt->need_login && be64_to_cpu(crq->event) == IBMVFC_AE_ELS_LOGO) | ^~ include/uapi/linux/byteorder/big_endian.h:38:51: note: in definition of macro '__be64_to_cpu' 38 | #define __be64_to_cpu(x) ((__force __u64)(__be64)(x)) | ^ drivers/scsi/ibmvscsi/ibmvfc.c:2722:27: note: in expansion of macro 'be64_to_cpu' 2722 | if (tgt->need_login && be64_to_cpu(crq->event) == IBMVFC_AE_ELS_LOGO) | ^~~~~~~~~~~ drivers/scsi/ibmvscsi/ibmvfc.c:2724:43: error: 'struct ibmvfc_async_crq' has no member named 'event' 2724 | if (!tgt->need_login || be64_to_cpu(crq->event) == IBMVFC_AE_ELS_PLOGI) { | ^~ include/uapi/linux/byteorder/big_endian.h:38:51: note: in definition of macro '__be64_to_cpu' 38 | #define __be64_to_cpu(x) ((__force __u64)(__be64)(x)) | ^ drivers/scsi/ibmvscsi/ibmvfc.c:2724:28: note: in expansion of macro 'be64_to_cpu' 2724 | if (!tgt->need_login || be64_to_cpu(crq->event) == IBMVFC_AE_ELS_PLOGI) { | ^~~~~~~~~~~ In file included from include/linux/device.h:15, from include/linux/dma-mapping.h:7, from drivers/scsi/ibmvscsi/ibmvfc.c:12: drivers/scsi/ibmvscsi/ibmvfc.c:2741:66: error: 'struct ibmvfc_async_crq' has no member named 'event' 2741 | dev_err(vhost->dev, "Unknown async event received: %lld\n", crq->event); | ^~ include/linux/dev_printk.h:104:32: note: in definition of macro 'dev_err' 104 | _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~ # https://github.com/0day-ci/linux/commit/b2aced49faf50075e9a74e7a253d1ad77cce1c0c git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Tyrel-Datwyler/scsi-ibmvfc-interface-updates-for-future-FPIN-and-MQ-support/20200901-012005 git checkout b2aced49faf50075e9a74e7a253d1ad77cce1c0c vim +500 drivers/scsi/ibmvscsi/ibmvfc.h 490 491 struct ibmvfc_channel_enquiry { 492 struct ibmvfc_mad_common common; 493 __be32 flags; 494 #define IBMVFC_NO_CHANNELS_TO_CRQ_SUPPORT 0x01 495 #define IBMVFC_SUPPORT_VARIABLE_SUBQ_MSG 0x02 496 #define IBMVFC_NO_N_TO_M_CHANNELS_SUPPORT 0x04 497 __be32 num_scsi_subq_channels; 498 __be32 num_nvmeof_subq_channels; 499 __be32 num_scsi_vas_channels; > 500 __be32 num nvmeof_vas_channels; 501 }__attribute__((packed, aligned (8))); 502 503 struct ibmvfc_channel_setup_mad { 504 struct ibmvfc_mad_common common; 505 struct srp_direct_buf buffer; > 506 }__attrribute__((packed, aligned (8))); 507 508 #define IBMVFC_MAX_CHANNELS 502 509 510 struct ibmvfc_channel_setup { 511 __be32 flags; 512 #define IBMVFC_CANCEL_CHANNELS 0x01 513 #define IBMVFC_USE_BUFFER 0x02 514 #define IBMVFC_CHANNELS_CANCELED 0x04 515 __be32 reserved; 516 __be32 num_scsi_subq_channels; 517 __be32 num_nvmeof_subq_channels; 518 __be32 num_scsi_vas_channels; 519 __be32 num_nvmeof_vas_channels; 520 struct srp_direct_buf buffer; 521 __be64 reserved2[5]; 522 __be64 channel_handles[IBMVFC_MAX_CHANNELS]; 523 }__attribute__((packed, aligned (8))); 524 525 struct ibmvfc_connection_info { > 526 struct ibmvfc_madd_common common; 527 __be64 information_bits; 528 #define IBMVFC_NO_FC_IO_CHANNEL 0x01 529 #define IBMVFC_NO_PHYP_VAS 0x02 530 #define IBMVFC_NO_PHYP_SUBQ 0x04 531 #define IBMVFC_PHYP_DEPRECATED_SUBQ 0x08 532 #define IBMVFC_PHYP_PRESERVED_SUBQ 0x10 533 #define IBMVFC_PHYP_FULL_SUBQ 0x20 534 __be64 reserved[16]; 535 }__attribute__((packed, aligned (8))); 536 537 struct ibmvfc_trace_start_entry { 538 u32 xfer_len; 539 }__attribute__((packed)); 540 541 struct ibmvfc_trace_end_entry { 542 u16 status; 543 u16 error; 544 u8 fcp_rsp_flags; 545 u8 rsp_code; 546 u8 scsi_status; 547 u8 reserved; 548 }__attribute__((packed)); 549 550 struct ibmvfc_trace_entry { 551 struct ibmvfc_event *evt; 552 u32 time; 553 u32 scsi_id; 554 u32 lun; 555 u8 fmt; 556 u8 op_code; 557 u8 tmf_flags; 558 u8 type; 559 #define IBMVFC_TRC_START 0x00 560 #define IBMVFC_TRC_END 0xff 561 union { 562 struct ibmvfc_trace_start_entry start; 563 struct ibmvfc_trace_end_entry end; 564 } u; 565 }__attribute__((packed, aligned (8))); 566 567 enum ibmvfc_crq_formats { 568 IBMVFC_CMD_FORMAT = 0x01, 569 IBMVFC_ASYNC_EVENT = 0x02, 570 IBMVFC_MAD_FORMAT = 0x04, 571 }; 572 573 enum ibmvfc_async_event { 574 IBMVFC_AE_ELS_PLOGI = 0x0001, 575 IBMVFC_AE_ELS_LOGO = 0x0002, 576 IBMVFC_AE_ELS_PRLO = 0x0004, 577 IBMVFC_AE_SCN_NPORT = 0x0008, 578 IBMVFC_AE_SCN_GROUP = 0x0010, 579 IBMVFC_AE_SCN_DOMAIN = 0x0020, 580 IBMVFC_AE_SCN_FABRIC = 0x0040, 581 IBMVFC_AE_LINK_UP = 0x0080, 582 IBMVFC_AE_LINK_DOWN = 0x0100, 583 IBMVFC_AE_LINK_DEAD = 0x0200, 584 IBMVFC_AE_HALT = 0x0400, 585 IBMVFC_AE_RESUME = 0x0800, 586 IBMVFC_AE_ADAPTER_FAILED = 0x1000, 587 IBMVFC_AE_FPIN = 0x2000, 588 }; 589 590 struct ibmvfc_async_desc { 591 const char *desc; 592 enum ibmvfc_async_event ae; 593 int log_level; 594 }; 595 596 struct ibmvfc_crq { 597 volatile u8 valid; 598 volatile u8 format; 599 u8 reserved[6]; 600 volatile __be64 ioba; 601 }__attribute__((packed, aligned (8))); 602 603 struct ibmvfc_crq_queue { 604 struct ibmvfc_crq *msgs; 605 int size, cur; 606 dma_addr_t msg_token; 607 }; 608 609 enum ibmvfc_ae_link_state { 610 IBMVFC_AE_LS_LINK_UP = 0x01, 611 IBMVFC_AE_LS_LINK_BOUNCED = 0x02, 612 IBMVFC_AE_LS_LINK_DOWN = 0x04, 613 IBMVFC_AE_LS_LINK_DEAD = 0x08, 614 }; 615 616 enum ibmvfc_ae_fpin_status { 617 IBMVFC_AE_FPIN_LINK_CONGESTED = 0x1, 618 IBMVFC_AE_FPIN_PORT_CONGESTED = 0x2, 619 IBMVFC_AE_FPIN_PORT_CLEARED = 0x3, 620 IBMVFC_AE_FPIN_PORT_DEGRADED = 0x4, 621 }; 622 623 struct ibmvfc_async_crq { 624 volatile u8 valid; 625 u8 link_state; 626 u8 fpin_status > 627 u8 pad; 628 __be32 pad2; 629 volatile __be64 event; 630 volatile __be64 scsi_id; 631 volatile __be64 wwpn; 632 volatile __be64 node_name; 633 __be64 reserved; 634 }__attribute__((packed, aligned (8))); 635 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index 907889f1fa9d..801681b63daa 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -124,6 +124,9 @@ enum ibmvfc_mad_types { IBMVFC_PASSTHRU = 0x0200, IBMVFC_TMF_MAD = 0x0100, IBMVFC_NPIV_LOGOUT = 0x0800, + IBMVFC_CHANNEL_ENQUIRY = 0x1000, + IBMVFC_CHANNEL_SETUP = 0x2000, + IBMVFC_CONNECTION_INFO = 0x4000, }; struct ibmvfc_mad_common { @@ -162,6 +165,8 @@ struct ibmvfc_npiv_login { __be32 max_cmds; __be64 capabilities; #define IBMVFC_CAN_MIGRATE 0x01 +#define IBMVFC_CAN_USE_CHANNELS 0x02 +#define IBMVFC_CAN_HANDLE_FPIN 0x04 __be64 node_name; struct srp_direct_buf async; u8 partition_name[IBMVFC_MAX_NAME]; @@ -204,6 +209,7 @@ struct ibmvfc_npiv_login_resp { __be64 capabilities; #define IBMVFC_CAN_FLUSH_ON_HALT 0x08 #define IBMVFC_CAN_SUPPRESS_ABTS 0x10 +#define IBMVFC_CAN_SUPPORT_CHANNELS 0x20 __be32 max_cmds; __be32 scsi_id_sz; __be64 max_dma_len; @@ -482,6 +488,52 @@ struct ibmvfc_passthru_mad { struct ibmvfc_passthru_fc_iu fc_iu; }__attribute__((packed, aligned (8))); +struct ibmvfc_channel_enquiry { + struct ibmvfc_mad_common common; + __be32 flags; +#define IBMVFC_NO_CHANNELS_TO_CRQ_SUPPORT 0x01 +#define IBMVFC_SUPPORT_VARIABLE_SUBQ_MSG 0x02 +#define IBMVFC_NO_N_TO_M_CHANNELS_SUPPORT 0x04 + __be32 num_scsi_subq_channels; + __be32 num_nvmeof_subq_channels; + __be32 num_scsi_vas_channels; + __be32 num nvmeof_vas_channels; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_channel_setup_mad { + struct ibmvfc_mad_common common; + struct srp_direct_buf buffer; +}__attrribute__((packed, aligned (8))); + +#define IBMVFC_MAX_CHANNELS 502 + +struct ibmvfc_channel_setup { + __be32 flags; +#define IBMVFC_CANCEL_CHANNELS 0x01 +#define IBMVFC_USE_BUFFER 0x02 +#define IBMVFC_CHANNELS_CANCELED 0x04 + __be32 reserved; + __be32 num_scsi_subq_channels; + __be32 num_nvmeof_subq_channels; + __be32 num_scsi_vas_channels; + __be32 num_nvmeof_vas_channels; + struct srp_direct_buf buffer; + __be64 reserved2[5]; + __be64 channel_handles[IBMVFC_MAX_CHANNELS]; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_connection_info { + struct ibmvfc_madd_common common; + __be64 information_bits; +#define IBMVFC_NO_FC_IO_CHANNEL 0x01 +#define IBMVFC_NO_PHYP_VAS 0x02 +#define IBMVFC_NO_PHYP_SUBQ 0x04 +#define IBMVFC_PHYP_DEPRECATED_SUBQ 0x08 +#define IBMVFC_PHYP_PRESERVED_SUBQ 0x10 +#define IBMVFC_PHYP_FULL_SUBQ 0x20 + __be64 reserved[16]; +}__attribute__((packed, aligned (8))); + struct ibmvfc_trace_start_entry { u32 xfer_len; }__attribute__((packed)); @@ -532,6 +584,7 @@ enum ibmvfc_async_event { IBMVFC_AE_HALT = 0x0400, IBMVFC_AE_RESUME = 0x0800, IBMVFC_AE_ADAPTER_FAILED = 0x1000, + IBMVFC_AE_FPIN = 0x2000, }; struct ibmvfc_async_desc { @@ -560,10 +613,18 @@ enum ibmvfc_ae_link_state { IBMVFC_AE_LS_LINK_DEAD = 0x08, }; +enum ibmvfc_ae_fpin_status { + IBMVFC_AE_FPIN_LINK_CONGESTED = 0x1, + IBMVFC_AE_FPIN_PORT_CONGESTED = 0x2, + IBMVFC_AE_FPIN_PORT_CLEARED = 0x3, + IBMVFC_AE_FPIN_PORT_DEGRADED = 0x4, +}; + struct ibmvfc_async_crq { volatile u8 valid; u8 link_state; - u8 pad[2]; + u8 fpin_status + u8 pad; __be32 pad2; volatile __be64 event; volatile __be64 scsi_id; @@ -590,6 +651,9 @@ union ibmvfc_iu { struct ibmvfc_tmf tmf; struct ibmvfc_cmd cmd; struct ibmvfc_passthru_mad passthru; + struct ibmvfc_channel_enquiry channel_enquiry; + struct ibmvfc_channel_setup_mad channel_setup; + struct ibmvfc_connection_info connection_info; }__attribute__((packed, aligned (8))); enum ibmvfc_target_action {
VIOS partitions with SLI-4 enabled Emulex adapters will be capable of driving IO in parallel through mulitple work queues or channels, and with new hyperviosr firmware that supports multiple interrupt sources an ibmvfc NPIV single initiator can be modified to exploit end to end channelization in a PowerVM environment. VIOS hosts will also be able to expose fabric perfromance impact notifications (FPIN) via a new asynchronous event to ibmvfc clients that advertise support via IBMVFC_CAN_HANDLE_FPIN in their capabilities flag during NPIV_LOGIN. This patch introduces three new Managment Datagrams (MADs) for channelization support negotiation as well as the FPIN asynchronous event and FPIN status flags. Follow up work is required to plumb the ibmvfc client driver to use these new interfaces. Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com> --- drivers/scsi/ibmvscsi/ibmvfc.h | 66 +++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-)