aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/virtio_console.c266
1 files changed, 133 insertions, 133 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index e1f92a0c5c5f..237eee26fbc3 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -855,6 +855,139 @@ static const struct file_operations port_debugfs_ops = {
855 .read = debugfs_read, 855 .read = debugfs_read,
856}; 856};
857 857
858static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
859{
860 struct port_buffer *buf;
861 unsigned int nr_added_bufs;
862 int ret;
863
864 nr_added_bufs = 0;
865 do {
866 buf = alloc_buf(PAGE_SIZE);
867 if (!buf)
868 break;
869
870 spin_lock_irq(lock);
871 ret = add_inbuf(vq, buf);
872 if (ret < 0) {
873 spin_unlock_irq(lock);
874 free_buf(buf);
875 break;
876 }
877 nr_added_bufs++;
878 spin_unlock_irq(lock);
879 } while (ret > 0);
880
881 return nr_added_bufs;
882}
883
884static int add_port(struct ports_device *portdev, u32 id)
885{
886 char debugfs_name[16];
887 struct port *port;
888 struct port_buffer *buf;
889 dev_t devt;
890 unsigned int nr_added_bufs;
891 int err;
892
893 port = kmalloc(sizeof(*port), GFP_KERNEL);
894 if (!port) {
895 err = -ENOMEM;
896 goto fail;
897 }
898
899 port->portdev = portdev;
900 port->id = id;
901
902 port->name = NULL;
903 port->inbuf = NULL;
904 port->cons.hvc = NULL;
905
906 port->host_connected = port->guest_connected = false;
907
908 port->in_vq = portdev->in_vqs[port->id];
909 port->out_vq = portdev->out_vqs[port->id];
910
911 cdev_init(&port->cdev, &port_fops);
912
913 devt = MKDEV(portdev->chr_major, id);
914 err = cdev_add(&port->cdev, devt, 1);
915 if (err < 0) {
916 dev_err(&port->portdev->vdev->dev,
917 "Error %d adding cdev for port %u\n", err, id);
918 goto free_port;
919 }
920 port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
921 devt, port, "vport%up%u",
922 port->portdev->drv_index, id);
923 if (IS_ERR(port->dev)) {
924 err = PTR_ERR(port->dev);
925 dev_err(&port->portdev->vdev->dev,
926 "Error %d creating device for port %u\n",
927 err, id);
928 goto free_cdev;
929 }
930
931 spin_lock_init(&port->inbuf_lock);
932 init_waitqueue_head(&port->waitqueue);
933
934 /* Fill the in_vq with buffers so the host can send us data. */
935 nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
936 if (!nr_added_bufs) {
937 dev_err(port->dev, "Error allocating inbufs\n");
938 err = -ENOMEM;
939 goto free_device;
940 }
941
942 /*
943 * If we're not using multiport support, this has to be a console port
944 */
945 if (!use_multiport(port->portdev)) {
946 err = init_port_console(port);
947 if (err)
948 goto free_inbufs;
949 }
950
951 spin_lock_irq(&portdev->ports_lock);
952 list_add_tail(&port->list, &port->portdev->ports);
953 spin_unlock_irq(&portdev->ports_lock);
954
955 /*
956 * Tell the Host we're set so that it can send us various
957 * configuration parameters for this port (eg, port name,
958 * caching, whether this is a console port, etc.)
959 */
960 send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
961
962 if (pdrvdata.debugfs_dir) {
963 /*
964 * Finally, create the debugfs file that we can use to
965 * inspect a port's state at any time
966 */
967 sprintf(debugfs_name, "vport%up%u",
968 port->portdev->drv_index, id);
969 port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
970 pdrvdata.debugfs_dir,
971 port,
972 &port_debugfs_ops);
973 }
974 return 0;
975
976free_inbufs:
977 while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
978 free_buf(buf);
979free_device:
980 device_destroy(pdrvdata.class, port->dev->devt);
981free_cdev:
982 cdev_del(&port->cdev);
983free_port:
984 kfree(port);
985fail:
986 /* The host might want to notify management sw about port add failure */
987 send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 0);
988 return err;
989}
990
858/* Remove all port-specific data. */ 991/* Remove all port-specific data. */
859static int remove_port(struct port *port) 992static int remove_port(struct port *port)
860{ 993{
@@ -1093,139 +1226,6 @@ static void config_intr(struct virtio_device *vdev)
1093 resize_console(find_port_by_id(portdev, 0)); 1226 resize_console(find_port_by_id(portdev, 0));
1094} 1227}
1095 1228
1096static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
1097{
1098 struct port_buffer *buf;
1099 unsigned int nr_added_bufs;
1100 int ret;
1101
1102 nr_added_bufs = 0;
1103 do {
1104 buf = alloc_buf(PAGE_SIZE);
1105 if (!buf)
1106 break;
1107
1108 spin_lock_irq(lock);
1109 ret = add_inbuf(vq, buf);
1110 if (ret < 0) {
1111 spin_unlock_irq(lock);
1112 free_buf(buf);
1113 break;
1114 }
1115 nr_added_bufs++;
1116 spin_unlock_irq(lock);
1117 } while (ret > 0);
1118
1119 return nr_added_bufs;
1120}
1121
1122static int add_port(struct ports_device *portdev, u32 id)
1123{
1124 char debugfs_name[16];
1125 struct port *port;
1126 struct port_buffer *buf;
1127 dev_t devt;
1128 unsigned int nr_added_bufs;
1129 int err;
1130
1131 port = kmalloc(sizeof(*port), GFP_KERNEL);
1132 if (!port) {
1133 err = -ENOMEM;
1134 goto fail;
1135 }
1136
1137 port->portdev = portdev;
1138 port->id = id;
1139
1140 port->name = NULL;
1141 port->inbuf = NULL;
1142 port->cons.hvc = NULL;
1143
1144 port->host_connected = port->guest_connected = false;
1145
1146 port->in_vq = portdev->in_vqs[port->id];
1147 port->out_vq = portdev->out_vqs[port->id];
1148
1149 cdev_init(&port->cdev, &port_fops);
1150
1151 devt = MKDEV(portdev->chr_major, id);
1152 err = cdev_add(&port->cdev, devt, 1);
1153 if (err < 0) {
1154 dev_err(&port->portdev->vdev->dev,
1155 "Error %d adding cdev for port %u\n", err, id);
1156 goto free_port;
1157 }
1158 port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
1159 devt, port, "vport%up%u",
1160 port->portdev->drv_index, id);
1161 if (IS_ERR(port->dev)) {
1162 err = PTR_ERR(port->dev);
1163 dev_err(&port->portdev->vdev->dev,
1164 "Error %d creating device for port %u\n",
1165 err, id);
1166 goto free_cdev;
1167 }
1168
1169 spin_lock_init(&port->inbuf_lock);
1170 init_waitqueue_head(&port->waitqueue);
1171
1172 /* Fill the in_vq with buffers so the host can send us data. */
1173 nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
1174 if (!nr_added_bufs) {
1175 dev_err(port->dev, "Error allocating inbufs\n");
1176 err = -ENOMEM;
1177 goto free_device;
1178 }
1179
1180 /*
1181 * If we're not using multiport support, this has to be a console port
1182 */
1183 if (!use_multiport(port->portdev)) {
1184 err = init_port_console(port);
1185 if (err)
1186 goto free_inbufs;
1187 }
1188
1189 spin_lock_irq(&portdev->ports_lock);
1190 list_add_tail(&port->list, &port->portdev->ports);
1191 spin_unlock_irq(&portdev->ports_lock);
1192
1193 /*
1194 * Tell the Host we're set so that it can send us various
1195 * configuration parameters for this port (eg, port name,
1196 * caching, whether this is a console port, etc.)
1197 */
1198 send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
1199
1200 if (pdrvdata.debugfs_dir) {
1201 /*
1202 * Finally, create the debugfs file that we can use to
1203 * inspect a port's state at any time
1204 */
1205 sprintf(debugfs_name, "vport%up%u",
1206 port->portdev->drv_index, id);
1207 port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
1208 pdrvdata.debugfs_dir,
1209 port,
1210 &port_debugfs_ops);
1211 }
1212 return 0;
1213
1214free_inbufs:
1215 while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
1216 free_buf(buf);
1217free_device:
1218 device_destroy(pdrvdata.class, port->dev->devt);
1219free_cdev:
1220 cdev_del(&port->cdev);
1221free_port:
1222 kfree(port);
1223fail:
1224 /* The host might want to notify management sw about port add failure */
1225 send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 0);
1226 return err;
1227}
1228
1229static int init_vqs(struct ports_device *portdev) 1229static int init_vqs(struct ports_device *portdev)
1230{ 1230{
1231 vq_callback_t **io_callbacks; 1231 vq_callback_t **io_callbacks;