ctrl.c (99f48ae7aea70fb080f04bf1cc846cd6450bd11a) | ctrl.c (1e9c685ec76e3b10de29c4ac7ad02d86cb5aeff1) |
---|---|
1/* 2 * QEMU NVM Express Controller 3 * 4 * Copyright (c) 2012, Intel Corporation 5 * 6 * Written by Keith Busch <keith.busch@intel.com> 7 * 8 * This code is licensed under the GNU GPL v2 or later. --- 5889 unchanged lines hidden (view full) --- 5898 nvme_admin_cmd(n, req); 5899 if (status != NVME_NO_COMPLETE) { 5900 req->status = status; 5901 nvme_enqueue_req_completion(cq, req); 5902 } 5903 } 5904} 5905 | 1/* 2 * QEMU NVM Express Controller 3 * 4 * Copyright (c) 2012, Intel Corporation 5 * 6 * Written by Keith Busch <keith.busch@intel.com> 7 * 8 * This code is licensed under the GNU GPL v2 or later. --- 5889 unchanged lines hidden (view full) --- 5898 nvme_admin_cmd(n, req); 5899 if (status != NVME_NO_COMPLETE) { 5900 req->status = status; 5901 nvme_enqueue_req_completion(cq, req); 5902 } 5903 } 5904} 5905 |
5906static void nvme_ctrl_reset(NvmeCtrl *n) | 5906static void nvme_ctrl_reset(NvmeCtrl *n, NvmeResetType rst) |
5907{ 5908 NvmeNamespace *ns; 5909 int i; 5910 5911 for (i = 1; i <= NVME_MAX_NAMESPACES; i++) { 5912 ns = nvme_ns(n, i); 5913 if (!ns) { 5914 continue; --- 15 unchanged lines hidden (view full) --- 5930 5931 while (!QTAILQ_EMPTY(&n->aer_queue)) { 5932 NvmeAsyncEvent *event = QTAILQ_FIRST(&n->aer_queue); 5933 QTAILQ_REMOVE(&n->aer_queue, event, entry); 5934 g_free(event); 5935 } 5936 5937 if (!pci_is_vf(&n->parent_obj) && n->params.sriov_max_vfs) { | 5907{ 5908 NvmeNamespace *ns; 5909 int i; 5910 5911 for (i = 1; i <= NVME_MAX_NAMESPACES; i++) { 5912 ns = nvme_ns(n, i); 5913 if (!ns) { 5914 continue; --- 15 unchanged lines hidden (view full) --- 5930 5931 while (!QTAILQ_EMPTY(&n->aer_queue)) { 5932 NvmeAsyncEvent *event = QTAILQ_FIRST(&n->aer_queue); 5933 QTAILQ_REMOVE(&n->aer_queue, event, entry); 5934 g_free(event); 5935 } 5936 5937 if (!pci_is_vf(&n->parent_obj) && n->params.sriov_max_vfs) { |
5938 pcie_sriov_pf_disable_vfs(&n->parent_obj); | 5938 if (rst != NVME_RESET_CONTROLLER) { 5939 pcie_sriov_pf_disable_vfs(&n->parent_obj); 5940 } |
5939 } 5940 5941 n->aer_queued = 0; 5942 n->outstanding_aers = 0; 5943 n->qs_created = false; 5944} 5945 5946static void nvme_ctrl_shutdown(NvmeCtrl *n) --- 217 unchanged lines hidden (view full) --- 6164 trace_pci_nvme_err_startfail(); 6165 csts = NVME_CSTS_FAILED; 6166 } else { 6167 trace_pci_nvme_mmio_start_success(); 6168 csts = NVME_CSTS_READY; 6169 } 6170 } else if (!NVME_CC_EN(data) && NVME_CC_EN(cc)) { 6171 trace_pci_nvme_mmio_stopped(); | 5941 } 5942 5943 n->aer_queued = 0; 5944 n->outstanding_aers = 0; 5945 n->qs_created = false; 5946} 5947 5948static void nvme_ctrl_shutdown(NvmeCtrl *n) --- 217 unchanged lines hidden (view full) --- 6166 trace_pci_nvme_err_startfail(); 6167 csts = NVME_CSTS_FAILED; 6168 } else { 6169 trace_pci_nvme_mmio_start_success(); 6170 csts = NVME_CSTS_READY; 6171 } 6172 } else if (!NVME_CC_EN(data) && NVME_CC_EN(cc)) { 6173 trace_pci_nvme_mmio_stopped(); |
6172 nvme_ctrl_reset(n); | 6174 nvme_ctrl_reset(n, NVME_RESET_CONTROLLER); |
6173 cc = 0; 6174 csts &= ~NVME_CSTS_READY; 6175 } 6176 6177 if (NVME_CC_SHN(data) && !(NVME_CC_SHN(cc))) { 6178 trace_pci_nvme_mmio_shutdown_set(); 6179 nvme_ctrl_shutdown(n); 6180 cc = data; --- 541 unchanged lines hidden (view full) --- 6722 pcie_sriov_pf_init(pci_dev, offset, "nvme", vf_dev_id, 6723 n->params.sriov_max_vfs, n->params.sriov_max_vfs, 6724 NVME_VF_OFFSET, NVME_VF_STRIDE); 6725 6726 pcie_sriov_pf_init_vf_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | 6727 PCI_BASE_ADDRESS_MEM_TYPE_64, bar_size); 6728} 6729 | 6175 cc = 0; 6176 csts &= ~NVME_CSTS_READY; 6177 } 6178 6179 if (NVME_CC_SHN(data) && !(NVME_CC_SHN(cc))) { 6180 trace_pci_nvme_mmio_shutdown_set(); 6181 nvme_ctrl_shutdown(n); 6182 cc = data; --- 541 unchanged lines hidden (view full) --- 6724 pcie_sriov_pf_init(pci_dev, offset, "nvme", vf_dev_id, 6725 n->params.sriov_max_vfs, n->params.sriov_max_vfs, 6726 NVME_VF_OFFSET, NVME_VF_STRIDE); 6727 6728 pcie_sriov_pf_init_vf_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | 6729 PCI_BASE_ADDRESS_MEM_TYPE_64, bar_size); 6730} 6731 |
6732static int nvme_add_pm_capability(PCIDevice *pci_dev, uint8_t offset) 6733{ 6734 Error *err = NULL; 6735 int ret; 6736 6737 ret = pci_add_capability(pci_dev, PCI_CAP_ID_PM, offset, 6738 PCI_PM_SIZEOF, &err); 6739 if (err) { 6740 error_report_err(err); 6741 return ret; 6742 } 6743 6744 pci_set_word(pci_dev->config + offset + PCI_PM_PMC, 6745 PCI_PM_CAP_VER_1_2); 6746 pci_set_word(pci_dev->config + offset + PCI_PM_CTRL, 6747 PCI_PM_CTRL_NO_SOFT_RESET); 6748 pci_set_word(pci_dev->wmask + offset + PCI_PM_CTRL, 6749 PCI_PM_CTRL_STATE_MASK); 6750 6751 return 0; 6752} 6753 |
|
6730static int nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp) 6731{ 6732 uint8_t *pci_conf = pci_dev->config; 6733 uint64_t bar_size, msix_table_size, msix_pba_size; 6734 unsigned msix_table_offset, msix_pba_offset; 6735 int ret; 6736 6737 Error *err = NULL; --- 5 unchanged lines hidden (view full) --- 6743 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); 6744 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_NVME); 6745 } else { 6746 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REDHAT); 6747 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REDHAT_NVME); 6748 } 6749 6750 pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_EXPRESS); | 6754static int nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp) 6755{ 6756 uint8_t *pci_conf = pci_dev->config; 6757 uint64_t bar_size, msix_table_size, msix_pba_size; 6758 unsigned msix_table_offset, msix_pba_offset; 6759 int ret; 6760 6761 Error *err = NULL; --- 5 unchanged lines hidden (view full) --- 6767 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); 6768 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_NVME); 6769 } else { 6770 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REDHAT); 6771 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REDHAT_NVME); 6772 } 6773 6774 pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_EXPRESS); |
6775 nvme_add_pm_capability(pci_dev, 0x60); |
|
6751 pcie_endpoint_cap_init(pci_dev, 0x80); | 6776 pcie_endpoint_cap_init(pci_dev, 0x80); |
6777 pcie_cap_flr_init(pci_dev); |
|
6752 if (n->params.sriov_max_vfs) { 6753 pcie_ari_init(pci_dev, 0x100, 1); 6754 } 6755 6756 bar_size = QEMU_ALIGN_UP(n->reg_size, 4 * KiB); 6757 msix_table_offset = bar_size; 6758 msix_table_size = PCI_MSIX_ENTRY_SIZE * n->params.msix_qsize; 6759 --- 234 unchanged lines hidden (view full) --- 6994} 6995 6996static void nvme_exit(PCIDevice *pci_dev) 6997{ 6998 NvmeCtrl *n = NVME(pci_dev); 6999 NvmeNamespace *ns; 7000 int i; 7001 | 6778 if (n->params.sriov_max_vfs) { 6779 pcie_ari_init(pci_dev, 0x100, 1); 6780 } 6781 6782 bar_size = QEMU_ALIGN_UP(n->reg_size, 4 * KiB); 6783 msix_table_offset = bar_size; 6784 msix_table_size = PCI_MSIX_ENTRY_SIZE * n->params.msix_qsize; 6785 --- 234 unchanged lines hidden (view full) --- 7020} 7021 7022static void nvme_exit(PCIDevice *pci_dev) 7023{ 7024 NvmeCtrl *n = NVME(pci_dev); 7025 NvmeNamespace *ns; 7026 int i; 7027 |
7002 nvme_ctrl_reset(n); | 7028 nvme_ctrl_reset(n, NVME_RESET_FUNCTION); |
7003 7004 if (n->subsys) { 7005 for (i = 1; i <= NVME_MAX_NAMESPACES; i++) { 7006 ns = nvme_ns(n, i); 7007 if (ns) { 7008 ns->attached--; 7009 } 7010 } --- 82 unchanged lines hidden (view full) --- 7093 /* only inject new bits of smart critical warning */ 7094 for (index = 0; index < NVME_SMART_WARN_MAX; index++) { 7095 event = 1 << index; 7096 if (value & ~old_value & event) 7097 nvme_smart_event(n, event); 7098 } 7099} 7100 | 7029 7030 if (n->subsys) { 7031 for (i = 1; i <= NVME_MAX_NAMESPACES; i++) { 7032 ns = nvme_ns(n, i); 7033 if (ns) { 7034 ns->attached--; 7035 } 7036 } --- 82 unchanged lines hidden (view full) --- 7119 /* only inject new bits of smart critical warning */ 7120 for (index = 0; index < NVME_SMART_WARN_MAX; index++) { 7121 event = 1 << index; 7122 if (value & ~old_value & event) 7123 nvme_smart_event(n, event); 7124 } 7125} 7126 |
7127static void nvme_pci_reset(DeviceState *qdev) 7128{ 7129 PCIDevice *pci_dev = PCI_DEVICE(qdev); 7130 NvmeCtrl *n = NVME(pci_dev); 7131 7132 trace_pci_nvme_pci_reset(); 7133 nvme_ctrl_reset(n, NVME_RESET_FUNCTION); 7134} 7135 7136static void nvme_pci_write_config(PCIDevice *dev, uint32_t address, 7137 uint32_t val, int len) 7138{ 7139 pci_default_write_config(dev, address, val, len); 7140 pcie_cap_flr_write_config(dev, address, val, len); 7141} 7142 |
|
7101static const VMStateDescription nvme_vmstate = { 7102 .name = "nvme", 7103 .unmigratable = 1, 7104}; 7105 7106static void nvme_class_init(ObjectClass *oc, void *data) 7107{ 7108 DeviceClass *dc = DEVICE_CLASS(oc); 7109 PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); 7110 7111 pc->realize = nvme_realize; | 7143static const VMStateDescription nvme_vmstate = { 7144 .name = "nvme", 7145 .unmigratable = 1, 7146}; 7147 7148static void nvme_class_init(ObjectClass *oc, void *data) 7149{ 7150 DeviceClass *dc = DEVICE_CLASS(oc); 7151 PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); 7152 7153 pc->realize = nvme_realize; |
7154 pc->config_write = nvme_pci_write_config; |
|
7112 pc->exit = nvme_exit; 7113 pc->class_id = PCI_CLASS_STORAGE_EXPRESS; 7114 pc->revision = 2; 7115 7116 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 7117 dc->desc = "Non-Volatile Memory Express"; 7118 device_class_set_props(dc, nvme_props); 7119 dc->vmsd = &nvme_vmstate; | 7155 pc->exit = nvme_exit; 7156 pc->class_id = PCI_CLASS_STORAGE_EXPRESS; 7157 pc->revision = 2; 7158 7159 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 7160 dc->desc = "Non-Volatile Memory Express"; 7161 device_class_set_props(dc, nvme_props); 7162 dc->vmsd = &nvme_vmstate; |
7163 dc->reset = nvme_pci_reset; |
|
7120} 7121 7122static void nvme_instance_init(Object *obj) 7123{ 7124 NvmeCtrl *n = NVME(obj); 7125 7126 device_add_bootindex_property(obj, &n->namespace.blkconf.bootindex, 7127 "bootindex", "/namespace@1,0", --- 32 unchanged lines hidden --- | 7164} 7165 7166static void nvme_instance_init(Object *obj) 7167{ 7168 NvmeCtrl *n = NVME(obj); 7169 7170 device_add_bootindex_property(obj, &n->namespace.blkconf.bootindex, 7171 "bootindex", "/namespace@1,0", --- 32 unchanged lines hidden --- |