Lines Matching +full:rx +full:- +full:slots
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for the Diolan DLN-2 USB adapter
8 * i2c-diolan-u2c.c
9 * Copyright (c) 2010-2011 Ericsson AB
66 /* if non-NULL the URB contains the response */
76 * the echo header field to index the slots field and find the receive context
80 /* RX slots bitmap */
83 /* used to wait for a free RX slot */
86 /* used to wait for an RX operation to complete */
87 struct dln2_rx_context slots[DLN2_MAX_RX_SLOTS]; member
123 struct dln2_dev *dln2 = dev_get_drvdata(pdev->dev.parent); in dln2_register_event_cb()
130 return -ENOMEM; in dln2_register_event_cb()
132 entry->id = id; in dln2_register_event_cb()
133 entry->callback = event_cb; in dln2_register_event_cb()
134 entry->pdev = pdev; in dln2_register_event_cb()
136 spin_lock_irqsave(&dln2->event_cb_lock, flags); in dln2_register_event_cb()
138 list_for_each_entry(i, &dln2->event_cb_list, list) { in dln2_register_event_cb()
139 if (i->id == id) { in dln2_register_event_cb()
140 ret = -EBUSY; in dln2_register_event_cb()
146 list_add_rcu(&entry->list, &dln2->event_cb_list); in dln2_register_event_cb()
148 spin_unlock_irqrestore(&dln2->event_cb_lock, flags); in dln2_register_event_cb()
159 struct dln2_dev *dln2 = dev_get_drvdata(pdev->dev.parent); in dln2_unregister_event_cb()
164 spin_lock_irqsave(&dln2->event_cb_lock, flags); in dln2_unregister_event_cb()
166 list_for_each_entry(i, &dln2->event_cb_list, list) { in dln2_unregister_event_cb()
167 if (i->id == id) { in dln2_unregister_event_cb()
168 list_del_rcu(&i->list); in dln2_unregister_event_cb()
174 spin_unlock_irqrestore(&dln2->event_cb_lock, flags); in dln2_unregister_event_cb()
191 struct device *dev = &dln2->interface->dev; in dln2_transfer_complete()
192 struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle]; in dln2_transfer_complete()
200 rxc = &rxs->slots[rx_slot]; in dln2_transfer_complete()
202 spin_lock_irqsave(&rxs->lock, flags); in dln2_transfer_complete()
203 if (rxc->in_use && !rxc->urb) { in dln2_transfer_complete()
204 rxc->urb = urb; in dln2_transfer_complete()
205 complete(&rxc->done); in dln2_transfer_complete()
208 spin_unlock_irqrestore(&rxs->lock, flags); in dln2_transfer_complete()
224 list_for_each_entry_rcu(i, &dln2->event_cb_list, list) { in dln2_run_event_callbacks()
225 if (i->id == id) { in dln2_run_event_callbacks()
226 i->callback(i->pdev, echo, data, len); in dln2_run_event_callbacks()
236 struct dln2_dev *dln2 = urb->context; in dln2_rx()
237 struct dln2_header *hdr = urb->transfer_buffer; in dln2_rx()
238 struct device *dev = &dln2->interface->dev; in dln2_rx()
244 switch (urb->status) { in dln2_rx()
248 case -ECONNRESET: in dln2_rx()
249 case -ENOENT: in dln2_rx()
250 case -ESHUTDOWN: in dln2_rx()
251 case -EPIPE: in dln2_rx()
253 dev_dbg(dev, "urb shutting down with status %d\n", urb->status); in dln2_rx()
256 dev_dbg(dev, "nonzero urb status received %d\n", urb->status); in dln2_rx()
260 if (urb->actual_length < sizeof(struct dln2_header)) { in dln2_rx()
261 dev_err(dev, "short response: %d\n", urb->actual_length); in dln2_rx()
265 handle = le16_to_cpu(hdr->handle); in dln2_rx()
266 id = le16_to_cpu(hdr->id); in dln2_rx()
267 echo = le16_to_cpu(hdr->echo); in dln2_rx()
268 size = le16_to_cpu(hdr->size); in dln2_rx()
270 if (size != urb->actual_length) { in dln2_rx()
272 handle, id, echo, size, urb->actual_length); in dln2_rx()
281 data = urb->transfer_buffer + sizeof(struct dln2_header); in dln2_rx()
282 len = urb->actual_length - sizeof(struct dln2_header); in dln2_rx()
287 spin_lock_irqsave(&dln2->event_cb_lock, flags); in dln2_rx()
289 spin_unlock_irqrestore(&dln2->event_cb_lock, flags); in dln2_rx()
291 /* URB will be re-submitted in _dln2_transfer (free_rx_slot) */ in dln2_rx()
299 dev_err(dev, "failed to resubmit RX URB: %d\n", err); in dln2_rx()
315 hdr->id = cpu_to_le16(cmd); in dln2_prep_buf()
316 hdr->size = cpu_to_le16(len); in dln2_prep_buf()
317 hdr->echo = cpu_to_le16(echo); in dln2_prep_buf()
318 hdr->handle = cpu_to_le16(handle); in dln2_prep_buf()
337 return -ENOMEM; in dln2_send_wait()
339 ret = usb_bulk_msg(dln2->usb_dev, in dln2_send_wait()
340 usb_sndbulkpipe(dln2->usb_dev, dln2->ep_out), in dln2_send_wait()
353 if (dln2->disconnect) { in find_free_slot()
354 *slot = -ENODEV; in find_free_slot()
358 rxs = &dln2->mod_rx_slots[handle]; in find_free_slot()
360 spin_lock_irqsave(&rxs->lock, flags); in find_free_slot()
362 *slot = find_first_zero_bit(rxs->bmap, DLN2_MAX_RX_SLOTS); in find_free_slot()
365 struct dln2_rx_context *rxc = &rxs->slots[*slot]; in find_free_slot()
367 set_bit(*slot, rxs->bmap); in find_free_slot()
368 rxc->in_use = true; in find_free_slot()
371 spin_unlock_irqrestore(&rxs->lock, flags); in find_free_slot()
385 ret = wait_event_interruptible(dln2->mod_rx_slots[handle].wq, in alloc_rx_slot()
400 rxs = &dln2->mod_rx_slots[handle]; in free_rx_slot()
402 spin_lock_irqsave(&rxs->lock, flags); in free_rx_slot()
404 clear_bit(slot, rxs->bmap); in free_rx_slot()
406 rxc = &rxs->slots[slot]; in free_rx_slot()
407 rxc->in_use = false; in free_rx_slot()
408 urb = rxc->urb; in free_rx_slot()
409 rxc->urb = NULL; in free_rx_slot()
410 reinit_completion(&rxc->done); in free_rx_slot()
412 spin_unlock_irqrestore(&rxs->lock, flags); in free_rx_slot()
416 struct device *dev = &dln2->interface->dev; in free_rx_slot()
420 dev_err(dev, "failed to resubmit RX URB: %d\n", err); in free_rx_slot()
423 wake_up_interruptible(&rxs->wq); in free_rx_slot()
434 struct device *dev = &dln2->interface->dev; in _dln2_transfer()
436 struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle]; in _dln2_transfer()
439 spin_lock(&dln2->disconnect_lock); in _dln2_transfer()
440 if (!dln2->disconnect) in _dln2_transfer()
441 dln2->active_transfers++; in _dln2_transfer()
443 ret = -ENODEV; in _dln2_transfer()
444 spin_unlock(&dln2->disconnect_lock); in _dln2_transfer()
461 rxc = &rxs->slots[rx_slot]; in _dln2_transfer()
463 ret = wait_for_completion_interruptible_timeout(&rxc->done, timeout); in _dln2_transfer()
466 ret = -ETIMEDOUT; in _dln2_transfer()
472 if (dln2->disconnect) { in _dln2_transfer()
473 ret = -ENODEV; in _dln2_transfer()
478 rsp = rxc->urb->transfer_buffer; in _dln2_transfer()
479 size = le16_to_cpu(rsp->hdr.size); in _dln2_transfer()
482 ret = -EPROTO; in _dln2_transfer()
486 if (le16_to_cpu(rsp->result) > 0x80) { in _dln2_transfer()
488 handle, le16_to_cpu(rsp->result)); in _dln2_transfer()
489 ret = -EREMOTEIO; in _dln2_transfer()
496 if (*ibuf_len > size - sizeof(*rsp)) in _dln2_transfer()
497 *ibuf_len = size - sizeof(*rsp); in _dln2_transfer()
504 spin_lock(&dln2->disconnect_lock); in _dln2_transfer()
505 dln2->active_transfers--; in _dln2_transfer()
506 spin_unlock(&dln2->disconnect_lock); in _dln2_transfer()
507 if (dln2->disconnect) in _dln2_transfer()
508 wake_up(&dln2->disconnect_wq); in _dln2_transfer()
521 dln2 = dev_get_drvdata(pdev->dev.parent); in dln2_transfer()
522 dln2_pdata = dev_get_platdata(&pdev->dev); in dln2_transfer()
523 handle = dln2_pdata->handle; in dln2_transfer()
541 return -EREMOTEIO; in dln2_check_hw()
544 dev_err(&dln2->interface->dev, "Device ID 0x%x not supported\n", in dln2_check_hw()
546 return -ENODEV; in dln2_check_hw()
557 struct device *dev = &dln2->interface->dev; in dln2_print_serialno()
564 return -EREMOTEIO; in dln2_print_serialno()
587 usb_free_urb(dln2->rx_urb[i]); in dln2_free_rx_urbs()
588 kfree(dln2->rx_buf[i]); in dln2_free_rx_urbs()
597 usb_kill_urb(dln2->rx_urb[i]); in dln2_stop_rx_urbs()
603 usb_put_dev(dln2->usb_dev); in dln2_free()
614 dln2->rx_buf[i] = kmalloc(rx_max_size, GFP_KERNEL); in dln2_setup_rx_urbs()
615 if (!dln2->rx_buf[i]) in dln2_setup_rx_urbs()
616 return -ENOMEM; in dln2_setup_rx_urbs()
618 dln2->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); in dln2_setup_rx_urbs()
619 if (!dln2->rx_urb[i]) in dln2_setup_rx_urbs()
620 return -ENOMEM; in dln2_setup_rx_urbs()
622 usb_fill_bulk_urb(dln2->rx_urb[i], dln2->usb_dev, in dln2_setup_rx_urbs()
623 usb_rcvbulkpipe(dln2->usb_dev, dln2->ep_in), in dln2_setup_rx_urbs()
624 dln2->rx_buf[i], rx_max_size, dln2_rx, dln2); in dln2_setup_rx_urbs()
632 struct device *dev = &dln2->interface->dev; in dln2_start_rx_urbs()
637 ret = usb_submit_urb(dln2->rx_urb[i], gfp); in dln2_start_rx_urbs()
639 dev_err(dev, "failed to submit RX URB: %d\n", ret); in dln2_start_rx_urbs()
694 .name = "dln2-gpio",
700 .name = "dln2-i2c",
706 .name = "dln2-spi",
712 .name = "dln2-adc",
724 spin_lock(&dln2->disconnect_lock); in dln2_stop()
725 dln2->disconnect = true; in dln2_stop()
726 spin_unlock(&dln2->disconnect_lock); in dln2_stop()
730 struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[i]; in dln2_stop()
733 spin_lock_irqsave(&rxs->lock, flags); in dln2_stop()
737 struct dln2_rx_context *rxc = &rxs->slots[j]; in dln2_stop()
739 if (rxc->in_use) in dln2_stop()
740 complete(&rxc->done); in dln2_stop()
743 spin_unlock_irqrestore(&rxs->lock, flags); in dln2_stop()
747 wait_event(dln2->disconnect_wq, !dln2->active_transfers); in dln2_stop()
758 mfd_remove_devices(&interface->dev); in dln2_disconnect()
766 struct usb_host_interface *hostif = interface->cur_altsetting; in dln2_probe()
769 struct device *dev = &interface->dev; in dln2_probe()
774 if (hostif->desc.bInterfaceNumber != 0) in dln2_probe()
775 return -ENODEV; in dln2_probe()
783 return -ENOMEM; in dln2_probe()
785 dln2->ep_out = epout->bEndpointAddress; in dln2_probe()
786 dln2->ep_in = epin->bEndpointAddress; in dln2_probe()
787 dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface)); in dln2_probe()
788 dln2->interface = interface; in dln2_probe()
790 init_waitqueue_head(&dln2->disconnect_wq); in dln2_probe()
793 init_waitqueue_head(&dln2->mod_rx_slots[i].wq); in dln2_probe()
794 spin_lock_init(&dln2->mod_rx_slots[i].lock); in dln2_probe()
796 init_completion(&dln2->mod_rx_slots[i].slots[j].done); in dln2_probe()
799 spin_lock_init(&dln2->event_cb_lock); in dln2_probe()
800 spin_lock_init(&dln2->disconnect_lock); in dln2_probe()
801 INIT_LIST_HEAD(&dln2->event_cb_list); in dln2_probe()
847 dln2->disconnect = false; in dln2_resume()