diff --git a/doc/source/cli/data/cinder.csv b/doc/source/cli/data/cinder.csv
index 310ae172b0..9fe6c9d685 100644
--- a/doc/source/cli/data/cinder.csv
+++ b/doc/source/cli/data/cinder.csv
@@ -94,7 +94,7 @@ quota-defaults,quota show --default,Lists default quotas for a tenant.
 quota-delete,quota delete --volume,Delete the quotas for a tenant.
 quota-show,quota show,Lists quotas for a tenant.
 quota-update,quota set,Updates quotas for a tenant.
-quota-usage,,Lists quota usage for a tenant.
+quota-usage,quota list --detail,Lists quota usage for a tenant.
 rate-limits,limits show --rate,Lists rate limits for a user.
 readonly-mode-update,volume set --read-only-mode | --read-write-mode,Updates volume read-only access-mode flag.
 rename,volume set --name,Renames a volume.
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index 0110feb668..8477da9079 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -143,6 +143,7 @@ class BaseQuota(object):
     def get_volume_quota(self, client, parsed_args):
         quota_class = (
             parsed_args.quota_class if 'quota_class' in parsed_args else False)
+        detail = parsed_args.detail if 'detail' in parsed_args else False
         default = parsed_args.default if 'default' in parsed_args else False
         try:
             if quota_class:
@@ -153,7 +154,7 @@ class BaseQuota(object):
                 if default:
                     quota = client.quotas.defaults(project)
                 else:
-                    quota = client.quotas.get(project)
+                    quota = client.quotas.get(project, usage=detail)
         except Exception as e:
             if type(e).__name__ == 'EndpointNotFound':
                 return {}
@@ -195,7 +196,7 @@ class BaseQuota(object):
                     # more consistent
                     for key, values in network_quota.items():
                         if type(values) is dict and "used" in values:
-                            values[u'in_use'] = values.pop("used")
+                            values['in_use'] = values.pop("used")
                         network_quota[key] = values
             return network_quota
         else:
@@ -205,7 +206,8 @@ class BaseQuota(object):
 class ListQuota(command.Lister, BaseQuota):
     _description = _(
         "List quotas for all projects with non-default quota values or "
-        "list detailed quota information for requested project")
+        "list detailed quota information for requested project"
+    )
 
     def _get_detailed_quotas(self, parsed_args):
         columns = (
@@ -222,10 +224,21 @@ class ListQuota(command.Lister, BaseQuota):
         )
         quotas = {}
         if parsed_args.compute:
-            quotas.update(self.get_compute_quota(
-                self.app.client_manager.compute, parsed_args))
+            quotas.update(
+                self.get_compute_quota(
+                    self.app.client_manager.compute,
+                    parsed_args,
+                )
+            )
         if parsed_args.network:
             quotas.update(self.get_network_quota(parsed_args))
+        if parsed_args.volume:
+            quotas.update(
+                self.get_volume_quota(
+                    self.app.client_manager.volume,
+                    parsed_args,
+                ),
+            )
 
         result = []
         for resource, values in quotas.items():
@@ -359,8 +372,7 @@ class ListQuota(command.Lister, BaseQuota):
 
         if parsed_args.volume:
             if parsed_args.detail:
-                LOG.warning("Volume service doesn't provide detailed quota"
-                            " information")
+                return self._get_detailed_quotas(parsed_args)
             volume_client = self.app.client_manager.volume
             for p in project_ids:
                 try:
diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py
index 087443c169..580072086d 100644
--- a/openstackclient/tests/unit/common/test_quota.py
+++ b/openstackclient/tests/unit/common/test_quota.py
@@ -279,6 +279,37 @@ class TestQuotaList(TestQuota):
         self.assertEqual(
             sorted(detailed_reference_data), sorted(ret_quotas))
 
+    def test_quota_list_details_volume(self):
+        detailed_quota = (
+            volume_fakes.FakeQuota.create_one_detailed_quota())
+
+        detailed_column_header = (
+            'Resource',
+            'In Use',
+            'Reserved',
+            'Limit',
+        )
+        detailed_reference_data = (
+            self._get_detailed_reference_data(detailed_quota))
+
+        self.volume.quotas.get = mock.Mock(return_value=detailed_quota)
+
+        arglist = [
+            '--detail',
+            '--volume',
+        ]
+        verifylist = [
+            ('detail', True),
+            ('volume', True),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+        ret_quotas = list(data)
+
+        self.assertEqual(detailed_column_header, columns)
+        self.assertEqual(sorted(detailed_reference_data), sorted(ret_quotas))
+
     def test_quota_list_compute(self):
         # Two projects with non-default quotas
         self.compute.quotas.get = mock.Mock(
@@ -1001,7 +1032,7 @@ class TestQuotaSet(TestQuota):
 class TestQuotaShow(TestQuota):
 
     def setUp(self):
-        super(TestQuotaShow, self).setUp()
+        super().setUp()
 
         self.compute_quota = compute_fakes.FakeQuota.create_one_comp_quota()
         self.compute_quotas_mock.get.return_value = self.compute_quota
@@ -1066,7 +1097,7 @@ class TestQuotaShow(TestQuota):
             self.projects[0].id, detail=False
         )
         self.volume_quotas_mock.get.assert_called_once_with(
-            self.projects[0].id,
+            self.projects[0].id, usage=False
         )
         self.network.get_quota.assert_called_once_with(
             self.projects[0].id, details=False
@@ -1128,7 +1159,7 @@ class TestQuotaShow(TestQuota):
             identity_fakes.project_id, detail=False
         )
         self.volume_quotas_mock.get.assert_called_once_with(
-            identity_fakes.project_id,
+            identity_fakes.project_id, usage=False
         )
         self.network.get_quota.assert_called_once_with(
             identity_fakes.project_id, details=False
diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py
index 96e381d3cc..6da69f8fcc 100644
--- a/openstackclient/tests/unit/volume/v2/fakes.py
+++ b/openstackclient/tests/unit/volume/v2/fakes.py
@@ -1193,6 +1193,35 @@ class FakeQuota(object):
 
         return quota
 
+    @staticmethod
+    def create_one_detailed_quota(attrs=None):
+        """Create one quota"""
+        attrs = attrs or {}
+
+        quota_attrs = {
+            'volumes': {'limit': 3, 'in_use': 1, 'reserved': 0},
+            'per_volume_gigabytes': {'limit': -1, 'in_use': 0, 'reserved': 0},
+            'snapshots': {'limit': 10, 'in_use': 0, 'reserved': 0},
+            'gigabytes': {'limit': 1000, 'in_use': 5, 'reserved': 0},
+            'backups': {'limit': 10, 'in_use': 0, 'reserved': 0},
+            'backup_gigabytes': {'limit': 1000, 'in_use': 0, 'reserved': 0},
+            'volumes_lvmdriver-1': {'limit': -1, 'in_use': 1, 'reserved': 0},
+            'gigabytes_lvmdriver-1': {'limit': -1, 'in_use': 5, 'reserved': 0},
+            'snapshots_lvmdriver-1': {'limit': -1, 'in_use': 0, 'reserved': 0},
+            'volumes___DEFAULT__': {'limit': -1, 'in_use': 0, 'reserved': 0},
+            'gigabytes___DEFAULT__': {'limit': -1, 'in_use': 0, 'reserved': 0},
+            'snapshots___DEFAULT__': {'limit': -1, 'in_use': 0, 'reserved': 0},
+            'groups': {'limit': 10, 'in_use': 0, 'reserved': 0},
+            'id': uuid.uuid4().hex,
+        }
+        quota_attrs.update(attrs)
+
+        quota = fakes.FakeResource(
+            info=copy.deepcopy(quota_attrs),
+            loaded=True)
+
+        return quota
+
 
 class FakeLimits(object):
     """Fake limits"""
diff --git a/releasenotes/notes/detailed-volume-quotas-198dc2e8f57ce1e7.yaml b/releasenotes/notes/detailed-volume-quotas-198dc2e8f57ce1e7.yaml
new file mode 100644
index 0000000000..bd0ef8522b
--- /dev/null
+++ b/releasenotes/notes/detailed-volume-quotas-198dc2e8f57ce1e7.yaml
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    The ``quota list`` command can now provide detailed quotas for the volume
+    service, e.g.::
+
+        $ openstack quota list --detail --volume