mtty.c (89345d5177aa0f6d678251e1e0870b0eeb1ab510) mtty.c (da44c340c4fe9d9653ae84fa6a60f406bafcffce)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Mediated virtual PCI serial host device driver
4 *
5 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
6 * Author: Neo Jia <cjia@nvidia.com>
7 * Kirti Wankhede <kwankhede@nvidia.com>
8 *

--- 129 unchanged lines hidden (view full) ---

138 u32 bar_mask[VFIO_PCI_NUM_REGIONS];
139 struct list_head next;
140 struct serial_port s[2];
141 struct mutex rxtx_lock;
142 struct vfio_device_info dev_info;
143 int nr_ports;
144};
145
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Mediated virtual PCI serial host device driver
4 *
5 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
6 * Author: Neo Jia <cjia@nvidia.com>
7 * Kirti Wankhede <kwankhede@nvidia.com>
8 *

--- 129 unchanged lines hidden (view full) ---

138 u32 bar_mask[VFIO_PCI_NUM_REGIONS];
139 struct list_head next;
140 struct serial_port s[2];
141 struct mutex rxtx_lock;
142 struct vfio_device_info dev_info;
143 int nr_ports;
144};
145
146static struct mtty_type {
147 struct mdev_type type;
148 int nr_ports;
149 const char *name;
150} mtty_types[2] = {
151 { .nr_ports = 1, .type.sysfs_name = "1", .name = "Single port serial" },
152 { .nr_ports = 2, .type.sysfs_name = "2", .name = "Dual port serial" },
153};
154
155static struct mdev_type *mtty_mdev_types[] = {
156 &mtty_types[0].type,
157 &mtty_types[1].type,
158};
159
146static atomic_t mdev_avail_ports = ATOMIC_INIT(MAX_MTTYS);
147
148static const struct file_operations vd_fops = {
149 .owner = THIS_MODULE,
150};
151
152static const struct vfio_device_ops mtty_dev_ops;
153

--- 548 unchanged lines hidden (view full) ---

702 return ret;
703}
704
705static int mtty_init_dev(struct vfio_device *vdev)
706{
707 struct mdev_state *mdev_state =
708 container_of(vdev, struct mdev_state, vdev);
709 struct mdev_device *mdev = to_mdev_device(vdev->dev);
160static atomic_t mdev_avail_ports = ATOMIC_INIT(MAX_MTTYS);
161
162static const struct file_operations vd_fops = {
163 .owner = THIS_MODULE,
164};
165
166static const struct vfio_device_ops mtty_dev_ops;
167

--- 548 unchanged lines hidden (view full) ---

716 return ret;
717}
718
719static int mtty_init_dev(struct vfio_device *vdev)
720{
721 struct mdev_state *mdev_state =
722 container_of(vdev, struct mdev_state, vdev);
723 struct mdev_device *mdev = to_mdev_device(vdev->dev);
710 int nr_ports = mdev_get_type_group_id(mdev) + 1;
724 struct mtty_type *type =
725 container_of(mdev->type, struct mtty_type, type);
711 int avail_ports = atomic_read(&mdev_avail_ports);
712 int ret;
713
714 do {
726 int avail_ports = atomic_read(&mdev_avail_ports);
727 int ret;
728
729 do {
715 if (avail_ports < nr_ports)
730 if (avail_ports < type->nr_ports)
716 return -ENOSPC;
717 } while (!atomic_try_cmpxchg(&mdev_avail_ports,
731 return -ENOSPC;
732 } while (!atomic_try_cmpxchg(&mdev_avail_ports,
718 &avail_ports, avail_ports - nr_ports));
733 &avail_ports,
734 avail_ports - type->nr_ports));
719
735
720 mdev_state->nr_ports = nr_ports;
736 mdev_state->nr_ports = type->nr_ports;
721 mdev_state->irq_index = -1;
722 mdev_state->s[0].max_fifo_size = MAX_FIFO_SIZE;
723 mdev_state->s[1].max_fifo_size = MAX_FIFO_SIZE;
724 mutex_init(&mdev_state->rxtx_lock);
725
726 mdev_state->vconfig = kzalloc(MTTY_CONFIG_SPACE_SIZE, GFP_KERNEL);
727 if (!mdev_state->vconfig) {
728 ret = -ENOMEM;
729 goto err_nr_ports;
730 }
731
732 mutex_init(&mdev_state->ops_lock);
733 mdev_state->mdev = mdev;
734 mtty_create_config_space(mdev_state);
735 return 0;
736
737err_nr_ports:
737 mdev_state->irq_index = -1;
738 mdev_state->s[0].max_fifo_size = MAX_FIFO_SIZE;
739 mdev_state->s[1].max_fifo_size = MAX_FIFO_SIZE;
740 mutex_init(&mdev_state->rxtx_lock);
741
742 mdev_state->vconfig = kzalloc(MTTY_CONFIG_SPACE_SIZE, GFP_KERNEL);
743 if (!mdev_state->vconfig) {
744 ret = -ENOMEM;
745 goto err_nr_ports;
746 }
747
748 mutex_init(&mdev_state->ops_lock);
749 mdev_state->mdev = mdev;
750 mtty_create_config_space(mdev_state);
751 return 0;
752
753err_nr_ports:
738 atomic_add(nr_ports, &mdev_avail_ports);
754 atomic_add(type->nr_ports, &mdev_avail_ports);
739 return ret;
740}
741
742static int mtty_probe(struct mdev_device *mdev)
743{
744 struct mdev_state *mdev_state;
745 int ret;
746

--- 490 unchanged lines hidden (view full) ---

1237static const struct attribute_group *mdev_dev_groups[] = {
1238 &mdev_dev_group,
1239 NULL,
1240};
1241
1242static ssize_t name_show(struct mdev_type *mtype,
1243 struct mdev_type_attribute *attr, char *buf)
1244{
755 return ret;
756}
757
758static int mtty_probe(struct mdev_device *mdev)
759{
760 struct mdev_state *mdev_state;
761 int ret;
762

--- 490 unchanged lines hidden (view full) ---

1253static const struct attribute_group *mdev_dev_groups[] = {
1254 &mdev_dev_group,
1255 NULL,
1256};
1257
1258static ssize_t name_show(struct mdev_type *mtype,
1259 struct mdev_type_attribute *attr, char *buf)
1260{
1245 static const char *name_str[2] = { "Single port serial",
1246 "Dual port serial" };
1261 struct mtty_type *type = container_of(mtype, struct mtty_type, type);
1247
1262
1248 return sysfs_emit(buf, "%s\n",
1249 name_str[mtype_get_type_group_id(mtype)]);
1263 return sysfs_emit(buf, "%s\n", type->name);
1250}
1251
1252static MDEV_TYPE_ATTR_RO(name);
1253
1254static ssize_t available_instances_show(struct mdev_type *mtype,
1255 struct mdev_type_attribute *attr,
1256 char *buf)
1257{
1264}
1265
1266static MDEV_TYPE_ATTR_RO(name);
1267
1268static ssize_t available_instances_show(struct mdev_type *mtype,
1269 struct mdev_type_attribute *attr,
1270 char *buf)
1271{
1258 unsigned int ports = mtype_get_type_group_id(mtype) + 1;
1272 struct mtty_type *type = container_of(mtype, struct mtty_type, type);
1259
1273
1260 return sprintf(buf, "%d\n", atomic_read(&mdev_avail_ports) / ports);
1274 return sprintf(buf, "%d\n", atomic_read(&mdev_avail_ports) /
1275 type->nr_ports);
1261}
1262
1263static MDEV_TYPE_ATTR_RO(available_instances);
1264
1265static ssize_t device_api_show(struct mdev_type *mtype,
1266 struct mdev_type_attribute *attr, char *buf)
1267{
1268 return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
1269}
1270
1271static MDEV_TYPE_ATTR_RO(device_api);
1272
1276}
1277
1278static MDEV_TYPE_ATTR_RO(available_instances);
1279
1280static ssize_t device_api_show(struct mdev_type *mtype,
1281 struct mdev_type_attribute *attr, char *buf)
1282{
1283 return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
1284}
1285
1286static MDEV_TYPE_ATTR_RO(device_api);
1287
1273static struct attribute *mdev_types_attrs[] = {
1288static const struct attribute *mdev_types_attrs[] = {
1274 &mdev_type_attr_name.attr,
1275 &mdev_type_attr_device_api.attr,
1276 &mdev_type_attr_available_instances.attr,
1277 NULL,
1278};
1279
1289 &mdev_type_attr_name.attr,
1290 &mdev_type_attr_device_api.attr,
1291 &mdev_type_attr_available_instances.attr,
1292 NULL,
1293};
1294
1280static struct attribute_group mdev_type_group1 = {
1281 .name = "1",
1282 .attrs = mdev_types_attrs,
1283};
1284
1285static struct attribute_group mdev_type_group2 = {
1286 .name = "2",
1287 .attrs = mdev_types_attrs,
1288};
1289
1290static struct attribute_group *mdev_type_groups[] = {
1291 &mdev_type_group1,
1292 &mdev_type_group2,
1293 NULL,
1294};
1295
1296static const struct vfio_device_ops mtty_dev_ops = {
1297 .name = "vfio-mtty",
1298 .init = mtty_init_dev,
1299 .release = mtty_release_dev,
1300 .read = mtty_read,
1301 .write = mtty_write,
1302 .ioctl = mtty_ioctl,
1303};
1304
1305static struct mdev_driver mtty_driver = {
1306 .driver = {
1307 .name = "mtty",
1308 .owner = THIS_MODULE,
1309 .mod_name = KBUILD_MODNAME,
1310 .dev_groups = mdev_dev_groups,
1311 },
1312 .probe = mtty_probe,
1313 .remove = mtty_remove,
1295static const struct vfio_device_ops mtty_dev_ops = {
1296 .name = "vfio-mtty",
1297 .init = mtty_init_dev,
1298 .release = mtty_release_dev,
1299 .read = mtty_read,
1300 .write = mtty_write,
1301 .ioctl = mtty_ioctl,
1302};
1303
1304static struct mdev_driver mtty_driver = {
1305 .driver = {
1306 .name = "mtty",
1307 .owner = THIS_MODULE,
1308 .mod_name = KBUILD_MODNAME,
1309 .dev_groups = mdev_dev_groups,
1310 },
1311 .probe = mtty_probe,
1312 .remove = mtty_remove,
1314 .supported_type_groups = mdev_type_groups,
1313 .types_attrs = mdev_types_attrs,
1315};
1316
1317static void mtty_device_release(struct device *dev)
1318{
1319 dev_dbg(dev, "mtty: released\n");
1320}
1321
1322static int __init mtty_dev_init(void)

--- 35 unchanged lines hidden (view full) ---

1358 mtty_dev.dev.release = mtty_device_release;
1359 dev_set_name(&mtty_dev.dev, "%s", MTTY_NAME);
1360
1361 ret = device_register(&mtty_dev.dev);
1362 if (ret)
1363 goto err_class;
1364
1365 ret = mdev_register_parent(&mtty_dev.parent, &mtty_dev.dev,
1314};
1315
1316static void mtty_device_release(struct device *dev)
1317{
1318 dev_dbg(dev, "mtty: released\n");
1319}
1320
1321static int __init mtty_dev_init(void)

--- 35 unchanged lines hidden (view full) ---

1357 mtty_dev.dev.release = mtty_device_release;
1358 dev_set_name(&mtty_dev.dev, "%s", MTTY_NAME);
1359
1360 ret = device_register(&mtty_dev.dev);
1361 if (ret)
1362 goto err_class;
1363
1364 ret = mdev_register_parent(&mtty_dev.parent, &mtty_dev.dev,
1366 &mtty_driver);
1365 &mtty_driver, mtty_mdev_types,
1366 ARRAY_SIZE(mtty_mdev_types));
1367 if (ret)
1368 goto err_device;
1369 return 0;
1370
1371err_device:
1372 device_unregister(&mtty_dev.dev);
1373err_class:
1374 class_destroy(mtty_dev.vd_class);

--- 30 unchanged lines hidden ---
1367 if (ret)
1368 goto err_device;
1369 return 0;
1370
1371err_device:
1372 device_unregister(&mtty_dev.dev);
1373err_class:
1374 class_destroy(mtty_dev.vd_class);

--- 30 unchanged lines hidden ---