Lines Matching +full:port +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0-only
27 static DEFINE_IDA(minors); /* minors for WWAN port chardevs */
38 /* WWAN port flags */
42 * struct wwan_device - The structure that defines a WWAN device
44 * @id: WWAN device unique ID.
46 * @port_id: Current available port ID to pick.
52 unsigned int id; member
63 * struct wwan_port - The structure that defines a WWAN port
64 * @type: Port type
65 * @start_count: Port start counter
66 * @flags: Store port state and capabilities
67 * @ops: Pointer to WWAN port operations
68 * @ops_lock: Protect port ops
71 * @waitqueue: The waitqueue for port fops (read/write/poll)
72 * @data_lock: Port specific data access serialization
75 * @at_data: AT port specific data
86 struct mutex data_lock; /* Port specific data access serialization */
101 return sprintf(buf, "%d\n", wwan->id); in index_show()
115 ida_free(&wwan_dev_ids, wwandev->id); in wwan_dev_destroy()
127 return (dev->type == &wwan_dev_type && in wwan_dev_parent_match()
128 (dev->parent == parent || dev == parent)); in wwan_dev_parent_match()
137 return ERR_PTR(-ENODEV); in wwan_dev_get_by_parent()
144 return dev->type == &wwan_dev_type && in wwan_dev_name_match()
154 return ERR_PTR(-ENODEV); in wwan_dev_get_by_name()
168 return wwandev->debugfs_dir; in wwan_get_debugfs_dir()
176 if (dev->type != &wwan_dev_type) in wwan_dev_debugfs_match()
181 return wwandev->debugfs_dir == dir; in wwan_dev_debugfs_match()
190 return ERR_PTR(-ENODEV); in wwan_dev_get_by_debugfs()
203 put_device(&wwandev->dev); in wwan_put_debugfs_dir()
204 put_device(&wwandev->dev); in wwan_put_debugfs_dir()
217 int err, id; in wwan_create_dev() local
219 /* The 'find-alloc-register' operation must be protected against in wwan_create_dev()
230 id = ida_alloc(&wwan_dev_ids, GFP_KERNEL); in wwan_create_dev()
231 if (id < 0) { in wwan_create_dev()
232 wwandev = ERR_PTR(id); in wwan_create_dev()
238 wwandev = ERR_PTR(-ENOMEM); in wwan_create_dev()
239 ida_free(&wwan_dev_ids, id); in wwan_create_dev()
243 wwandev->dev.parent = parent; in wwan_create_dev()
244 wwandev->dev.class = &wwan_class; in wwan_create_dev()
245 wwandev->dev.type = &wwan_dev_type; in wwan_create_dev()
246 wwandev->id = id; in wwan_create_dev()
247 dev_set_name(&wwandev->dev, "wwan%d", wwandev->id); in wwan_create_dev()
249 err = device_register(&wwandev->dev); in wwan_create_dev()
251 put_device(&wwandev->dev); in wwan_create_dev()
257 wwandev->debugfs_dir = in wwan_create_dev()
258 debugfs_create_dir(kobject_name(&wwandev->dev.kobj), in wwan_create_dev()
270 return dev->class == &wwan_class; in is_wwan_child()
281 * child port, and subsequent port registrations only grab a reference in wwan_remove_dev()
283 * its last port, and reference simply dropped (put) otherwise. In the in wwan_remove_dev()
286 if (wwandev->ops) in wwan_remove_dev()
289 ret = device_for_each_child(&wwandev->dev, NULL, is_wwan_child); in wwan_remove_dev()
293 debugfs_remove_recursive(wwandev->debugfs_dir); in wwan_remove_dev()
295 device_unregister(&wwandev->dev); in wwan_remove_dev()
297 put_device(&wwandev->dev); in wwan_remove_dev()
303 /* ------- WWAN port management ------- */
306 const char * const name; /* Port type name */
307 const char * const devsuf; /* Port device name suffix */
342 struct wwan_port *port = to_wwan_port(dev); in type_show() local
344 return sprintf(buf, "%s\n", wwan_port_types[port->type].name); in type_show()
356 struct wwan_port *port = to_wwan_port(dev); in wwan_port_destroy() local
358 ida_free(&minors, MINOR(port->dev.devt)); in wwan_port_destroy()
359 mutex_destroy(&port->data_lock); in wwan_port_destroy()
360 mutex_destroy(&port->ops_lock); in wwan_port_destroy()
361 kfree(port); in wwan_port_destroy()
372 return (dev->type == &wwan_port_dev_type && in wwan_port_minor_match()
373 MINOR(dev->devt) == *(unsigned int *)minor); in wwan_port_minor_match()
382 return ERR_PTR(-ENODEV); in wwan_port_get_by_minor()
392 * To avoid names collision, the caller must prevent the new port device
395 static int __wwan_port_dev_assign_name(struct wwan_port *port, const char *fmt) in __wwan_port_dev_assign_name() argument
397 struct wwan_device *wwandev = to_wwan_dev(port->dev.parent); in __wwan_port_dev_assign_name()
403 int id; in __wwan_port_dev_assign_name() local
407 return -ENOMEM; in __wwan_port_dev_assign_name()
412 if (dev->parent != &wwandev->dev) in __wwan_port_dev_assign_name()
414 if (sscanf(dev_name(dev), fmt, &id) != 1) in __wwan_port_dev_assign_name()
416 if (id < 0 || id >= max_ports) in __wwan_port_dev_assign_name()
418 set_bit(id, idmap); in __wwan_port_dev_assign_name()
422 /* Allocate unique id */ in __wwan_port_dev_assign_name()
423 id = find_first_zero_bit(idmap, max_ports); in __wwan_port_dev_assign_name()
426 snprintf(buf, sizeof(buf), fmt, id); /* Name generation */ in __wwan_port_dev_assign_name()
428 dev = device_find_child_by_name(&wwandev->dev, buf); in __wwan_port_dev_assign_name()
431 return -ENFILE; in __wwan_port_dev_assign_name()
434 return dev_set_name(&port->dev, buf); in __wwan_port_dev_assign_name()
444 struct wwan_port *port; in wwan_create_port() local
449 return ERR_PTR(-EINVAL); in wwan_create_port()
451 /* A port is always a child of a WWAN device, retrieve (allocate or in wwan_create_port()
458 /* A port is exposed as character device, get a minor */ in wwan_create_port()
459 minor = ida_alloc_range(&minors, 0, WWAN_MAX_MINORS - 1, GFP_KERNEL); in wwan_create_port()
465 port = kzalloc(sizeof(*port), GFP_KERNEL); in wwan_create_port()
466 if (!port) { in wwan_create_port()
467 err = -ENOMEM; in wwan_create_port()
472 port->type = type; in wwan_create_port()
473 port->ops = ops; in wwan_create_port()
474 port->frag_len = caps ? caps->frag_len : SIZE_MAX; in wwan_create_port()
475 port->headroom_len = caps ? caps->headroom_len : 0; in wwan_create_port()
476 mutex_init(&port->ops_lock); in wwan_create_port()
477 skb_queue_head_init(&port->rxq); in wwan_create_port()
478 init_waitqueue_head(&port->waitqueue); in wwan_create_port()
479 mutex_init(&port->data_lock); in wwan_create_port()
481 port->dev.parent = &wwandev->dev; in wwan_create_port()
482 port->dev.class = &wwan_class; in wwan_create_port()
483 port->dev.type = &wwan_port_dev_type; in wwan_create_port()
484 port->dev.devt = MKDEV(wwan_major, minor); in wwan_create_port()
485 dev_set_drvdata(&port->dev, drvdata); in wwan_create_port()
487 /* allocate unique name based on wwan device id, port type and number */ in wwan_create_port()
488 snprintf(namefmt, sizeof(namefmt), "wwan%u%s%%d", wwandev->id, in wwan_create_port()
489 wwan_port_types[port->type].devsuf); in wwan_create_port()
494 __wwan_port_dev_assign_name(port, namefmt); in wwan_create_port()
495 err = device_register(&port->dev); in wwan_create_port()
502 dev_info(&wwandev->dev, "port %s attached\n", dev_name(&port->dev)); in wwan_create_port()
503 return port; in wwan_create_port()
506 put_device(&port->dev); in wwan_create_port()
514 void wwan_remove_port(struct wwan_port *port) in wwan_remove_port() argument
516 struct wwan_device *wwandev = to_wwan_dev(port->dev.parent); in wwan_remove_port()
518 mutex_lock(&port->ops_lock); in wwan_remove_port()
519 if (port->start_count) in wwan_remove_port()
520 port->ops->stop(port); in wwan_remove_port()
521 port->ops = NULL; /* Prevent any new port operations (e.g. from fops) */ in wwan_remove_port()
522 mutex_unlock(&port->ops_lock); in wwan_remove_port()
524 wake_up_interruptible(&port->waitqueue); in wwan_remove_port()
526 skb_queue_purge(&port->rxq); in wwan_remove_port()
527 dev_set_drvdata(&port->dev, NULL); in wwan_remove_port()
529 dev_info(&wwandev->dev, "port %s disconnected\n", dev_name(&port->dev)); in wwan_remove_port()
530 device_unregister(&port->dev); in wwan_remove_port()
537 void wwan_port_rx(struct wwan_port *port, struct sk_buff *skb) in wwan_port_rx() argument
539 skb_queue_tail(&port->rxq, skb); in wwan_port_rx()
540 wake_up_interruptible(&port->waitqueue); in wwan_port_rx()
544 void wwan_port_txon(struct wwan_port *port) in wwan_port_txon() argument
546 clear_bit(WWAN_PORT_TX_OFF, &port->flags); in wwan_port_txon()
547 wake_up_interruptible(&port->waitqueue); in wwan_port_txon()
551 void wwan_port_txoff(struct wwan_port *port) in wwan_port_txoff() argument
553 set_bit(WWAN_PORT_TX_OFF, &port->flags); in wwan_port_txoff()
557 void *wwan_port_get_drvdata(struct wwan_port *port) in wwan_port_get_drvdata() argument
559 return dev_get_drvdata(&port->dev); in wwan_port_get_drvdata()
563 static int wwan_port_op_start(struct wwan_port *port) in wwan_port_op_start() argument
567 mutex_lock(&port->ops_lock); in wwan_port_op_start()
568 if (!port->ops) { /* Port got unplugged */ in wwan_port_op_start()
569 ret = -ENODEV; in wwan_port_op_start()
573 /* If port is already started, don't start again */ in wwan_port_op_start()
574 if (!port->start_count) in wwan_port_op_start()
575 ret = port->ops->start(port); in wwan_port_op_start()
578 port->start_count++; in wwan_port_op_start()
581 mutex_unlock(&port->ops_lock); in wwan_port_op_start()
586 static void wwan_port_op_stop(struct wwan_port *port) in wwan_port_op_stop() argument
588 mutex_lock(&port->ops_lock); in wwan_port_op_stop()
589 port->start_count--; in wwan_port_op_stop()
590 if (!port->start_count) { in wwan_port_op_stop()
591 if (port->ops) in wwan_port_op_stop()
592 port->ops->stop(port); in wwan_port_op_stop()
593 skb_queue_purge(&port->rxq); in wwan_port_op_stop()
595 mutex_unlock(&port->ops_lock); in wwan_port_op_stop()
598 static int wwan_port_op_tx(struct wwan_port *port, struct sk_buff *skb, in wwan_port_op_tx() argument
603 mutex_lock(&port->ops_lock); in wwan_port_op_tx()
604 if (!port->ops) { /* Port got unplugged */ in wwan_port_op_tx()
605 ret = -ENODEV; in wwan_port_op_tx()
609 if (nonblock || !port->ops->tx_blocking) in wwan_port_op_tx()
610 ret = port->ops->tx(port, skb); in wwan_port_op_tx()
612 ret = port->ops->tx_blocking(port, skb); in wwan_port_op_tx()
615 mutex_unlock(&port->ops_lock); in wwan_port_op_tx()
620 static bool is_read_blocked(struct wwan_port *port) in is_read_blocked() argument
622 return skb_queue_empty(&port->rxq) && port->ops; in is_read_blocked()
625 static bool is_write_blocked(struct wwan_port *port) in is_write_blocked() argument
627 return test_bit(WWAN_PORT_TX_OFF, &port->flags) && port->ops; in is_write_blocked()
630 static int wwan_wait_rx(struct wwan_port *port, bool nonblock) in wwan_wait_rx() argument
632 if (!is_read_blocked(port)) in wwan_wait_rx()
636 return -EAGAIN; in wwan_wait_rx()
638 if (wait_event_interruptible(port->waitqueue, !is_read_blocked(port))) in wwan_wait_rx()
639 return -ERESTARTSYS; in wwan_wait_rx()
644 static int wwan_wait_tx(struct wwan_port *port, bool nonblock) in wwan_wait_tx() argument
646 if (!is_write_blocked(port)) in wwan_wait_tx()
650 return -EAGAIN; in wwan_wait_tx()
652 if (wait_event_interruptible(port->waitqueue, !is_write_blocked(port))) in wwan_wait_tx()
653 return -ERESTARTSYS; in wwan_wait_tx()
660 struct wwan_port *port; in wwan_port_fops_open() local
663 port = wwan_port_get_by_minor(iminor(inode)); in wwan_port_fops_open()
664 if (IS_ERR(port)) in wwan_port_fops_open()
665 return PTR_ERR(port); in wwan_port_fops_open()
667 file->private_data = port; in wwan_port_fops_open()
670 err = wwan_port_op_start(port); in wwan_port_fops_open()
672 put_device(&port->dev); in wwan_port_fops_open()
679 struct wwan_port *port = filp->private_data; in wwan_port_fops_release() local
681 wwan_port_op_stop(port); in wwan_port_fops_release()
682 put_device(&port->dev); in wwan_port_fops_release()
690 struct wwan_port *port = filp->private_data; in wwan_port_fops_read() local
695 ret = wwan_wait_rx(port, !!(filp->f_flags & O_NONBLOCK)); in wwan_port_fops_read()
699 skb = skb_dequeue(&port->rxq); in wwan_port_fops_read()
701 return -EIO; in wwan_port_fops_read()
703 copied = min_t(size_t, count, skb->len); in wwan_port_fops_read()
704 if (copy_to_user(buf, skb->data, copied)) { in wwan_port_fops_read()
706 return -EFAULT; in wwan_port_fops_read()
711 if (skb->len) in wwan_port_fops_read()
712 skb_queue_head(&port->rxq, skb); in wwan_port_fops_read()
723 struct wwan_port *port = filp->private_data; in wwan_port_fops_write() local
727 ret = wwan_wait_tx(port, !!(filp->f_flags & O_NONBLOCK)); in wwan_port_fops_write()
732 frag_len = min(remain, port->frag_len); in wwan_port_fops_write()
733 skb = alloc_skb(frag_len + port->headroom_len, GFP_KERNEL); in wwan_port_fops_write()
735 ret = -ENOMEM; in wwan_port_fops_write()
738 skb_reserve(skb, port->headroom_len); in wwan_port_fops_write()
743 skb_shinfo(head)->frag_list = skb; in wwan_port_fops_write()
746 tail->next = skb; in wwan_port_fops_write()
750 if (copy_from_user(skb_put(skb, frag_len), buf + count - remain, frag_len)) { in wwan_port_fops_write()
751 ret = -EFAULT; in wwan_port_fops_write()
756 head->data_len += skb->len; in wwan_port_fops_write()
757 head->len += skb->len; in wwan_port_fops_write()
758 head->truesize += skb->truesize; in wwan_port_fops_write()
760 } while (remain -= frag_len); in wwan_port_fops_write()
762 ret = wwan_port_op_tx(port, head, !!(filp->f_flags & O_NONBLOCK)); in wwan_port_fops_write()
773 struct wwan_port *port = filp->private_data; in wwan_port_fops_poll() local
776 poll_wait(filp, &port->waitqueue, wait); in wwan_port_fops_poll()
778 mutex_lock(&port->ops_lock); in wwan_port_fops_poll()
779 if (port->ops && port->ops->tx_poll) in wwan_port_fops_poll()
780 mask |= port->ops->tx_poll(port, filp, wait); in wwan_port_fops_poll()
781 else if (!is_write_blocked(port)) in wwan_port_fops_poll()
783 if (!is_read_blocked(port)) in wwan_port_fops_poll()
785 if (!port->ops) in wwan_port_fops_poll()
787 mutex_unlock(&port->ops_lock); in wwan_port_fops_poll()
793 static long wwan_port_fops_at_ioctl(struct wwan_port *port, unsigned int cmd, in wwan_port_fops_at_ioctl() argument
798 mutex_lock(&port->data_lock); in wwan_port_fops_at_ioctl()
805 if (copy_to_user((void __user *)arg, &port->at_data.termios, in wwan_port_fops_at_ioctl()
807 ret = -EFAULT; in wwan_port_fops_at_ioctl()
813 if (copy_from_user(&port->at_data.termios, (void __user *)arg, in wwan_port_fops_at_ioctl()
815 ret = -EFAULT; in wwan_port_fops_at_ioctl()
820 if (copy_to_user((void __user *)arg, &port->at_data.termios, in wwan_port_fops_at_ioctl()
822 ret = -EFAULT; in wwan_port_fops_at_ioctl()
828 if (copy_from_user(&port->at_data.termios, (void __user *)arg, in wwan_port_fops_at_ioctl()
830 ret = -EFAULT; in wwan_port_fops_at_ioctl()
835 ret = put_user(port->at_data.mdmbits, (int __user *)arg); in wwan_port_fops_at_ioctl()
844 ret = -EFAULT; in wwan_port_fops_at_ioctl()
848 port->at_data.mdmbits &= ~mdmbits; in wwan_port_fops_at_ioctl()
850 port->at_data.mdmbits |= mdmbits; in wwan_port_fops_at_ioctl()
852 port->at_data.mdmbits = mdmbits; in wwan_port_fops_at_ioctl()
857 ret = -ENOIOCTLCMD; in wwan_port_fops_at_ioctl()
860 mutex_unlock(&port->data_lock); in wwan_port_fops_at_ioctl()
868 struct wwan_port *port = filp->private_data; in wwan_port_fops_ioctl() local
871 if (port->type == WWAN_PORT_AT) { /* AT port specific IOCTLs */ in wwan_port_fops_ioctl()
872 res = wwan_port_fops_at_ioctl(port, cmd, arg); in wwan_port_fops_ioctl()
873 if (res != -ENOIOCTLCMD) in wwan_port_fops_ioctl()
883 spin_lock_irqsave(&port->rxq.lock, flags); in wwan_port_fops_ioctl()
884 skb_queue_walk(&port->rxq, skb) in wwan_port_fops_ioctl()
885 amount += skb->len; in wwan_port_fops_ioctl()
886 spin_unlock_irqrestore(&port->rxq.lock, flags); in wwan_port_fops_ioctl()
892 return -ENOIOCTLCMD; in wwan_port_fops_ioctl()
914 return -EINVAL; in wwan_rtnl_validate()
917 return -EINVAL; in wwan_rtnl_validate()
920 return -EINVAL; in wwan_rtnl_validate()
942 if (!wwandev->ops) { in wwan_rtnl_alloc()
943 dev = ERR_PTR(-EOPNOTSUPP); in wwan_rtnl_alloc()
947 priv_size = sizeof(struct wwan_netdev_priv) + wwandev->ops->priv_size; in wwan_rtnl_alloc()
949 wwandev->ops->setup, num_tx_queues, num_rx_queues); in wwan_rtnl_alloc()
952 SET_NETDEV_DEV(dev, &wwandev->dev); in wwan_rtnl_alloc()
958 put_device(&wwandev->dev); in wwan_rtnl_alloc()
966 struct wwan_device *wwandev = wwan_dev_get_by_parent(dev->dev.parent); in wwan_rtnl_newlink()
975 if (WARN_ON(!wwandev->ops)) { in wwan_rtnl_newlink()
976 ret = -EOPNOTSUPP; in wwan_rtnl_newlink()
980 priv->link_id = link_id; in wwan_rtnl_newlink()
981 if (wwandev->ops->newlink) in wwan_rtnl_newlink()
982 ret = wwandev->ops->newlink(wwandev->ops_ctxt, dev, in wwan_rtnl_newlink()
989 put_device(&wwandev->dev); in wwan_rtnl_newlink()
995 struct wwan_device *wwandev = wwan_dev_get_by_parent(dev->dev.parent); in wwan_rtnl_dellink()
1001 if (WARN_ON(!wwandev->ops)) in wwan_rtnl_dellink()
1004 if (wwandev->ops->dellink) in wwan_rtnl_dellink()
1005 wwandev->ops->dellink(wwandev->ops_ctxt, dev, head); in wwan_rtnl_dellink()
1011 put_device(&wwandev->dev); in wwan_rtnl_dellink()
1026 if (nla_put_u32(skb, IFLA_WWAN_LINK_ID, priv->link_id)) in wwan_rtnl_fill_info()
1032 return -EMSGSIZE; in wwan_rtnl_fill_info()
1071 if (nla_put_string(msg, IFLA_PARENT_DEV_NAME, dev_name(&wwandev->dev))) in wwan_create_default_link()
1115 * wwan_register_ops - register WWAN device ops
1120 * @def_link_id: id of the default link that will be automatically created by
1131 if (WARN_ON(!parent || !ops || !ops->setup)) in wwan_register_ops()
1132 return -EINVAL; in wwan_register_ops()
1138 if (WARN_ON(wwandev->ops)) { in wwan_register_ops()
1140 return -EBUSY; in wwan_register_ops()
1143 wwandev->ops = ops; in wwan_register_ops()
1144 wwandev->ops_ctxt = ctxt; in wwan_register_ops()
1164 if (dev->type == &wwan_type) in wwan_child_dellink()
1171 * wwan_unregister_ops - remove WWAN device ops
1182 if (WARN_ON(!wwandev->ops)) { in wwan_unregister_ops()
1183 put_device(&wwandev->dev); in wwan_unregister_ops()
1191 put_device(&wwandev->dev); in wwan_unregister_ops()
1196 device_for_each_child(&wwandev->dev, &kill_list, in wwan_unregister_ops()
1200 wwandev->ops = NULL; /* Finally remove ops */ in wwan_unregister_ops()
1204 wwandev->ops_ctxt = NULL; in wwan_unregister_ops()