source: mainline/uspace/drv/bus/usb/usbdiag/main.c@ cbb37b6

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since cbb37b6 was 7cba9f7, checked in by Petr Manek <petr.manek@…>, 8 years ago

usbdiag: refactor to errno_t

  • Property mode set to 100644
File size: 7.9 KB
RevLine 
[d23fab9]1/*
2 * Copyright (c) 2017 Petr Manek
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[b7e1458]29/** @addtogroup drvusbdiag
[d23fab9]30 * @{
31 */
32/**
33 * @file
[a8723748]34 * Main routines of USB diagnostic device driver.
[d23fab9]35 */
36#include <errno.h>
37#include <usb/debug.h>
[47a9633]38#include <usb/classes/classes.h>
[d23fab9]39#include <usb/dev/driver.h>
[41ebc36]40#include <usbdiag_iface.h>
[64d138b]41#include <str_error.h>
[d23fab9]42
[6c8a221c]43#include "device.h"
44
[b7e1458]45#define NAME "usbdiag"
[d23fab9]46
[b3c39690]47static const usb_endpoint_description_t *diag_endpoints[];
48
[7cba9f7]49static errno_t device_add(usb_device_t *dev)
[d23fab9]50{
[7cba9f7]51 errno_t rc;
[6c8a221c]52 usb_log_info("Adding device '%s'", usb_device_get_name(dev));
53
[b7b7898]54 usbdiag_dev_t *diag_dev;
[b3c39690]55 if ((rc = usbdiag_dev_create(dev, &diag_dev, diag_endpoints))) {
[a1732929]56 usb_log_error("Failed create device: %s.", str_error(rc));
[64d138b]57 goto err;
58 }
59
60 if ((rc = ddf_fun_bind(diag_dev->fun))) {
[a1732929]61 usb_log_error("Failed to bind DDF function: %s.", str_error(rc));
[64d138b]62 goto err_create;
63 }
[6c8a221c]64
[41ebc36]65 if ((rc = ddf_fun_add_to_category(diag_dev->fun, USBDIAG_CATEGORY))) {
[64d138b]66 usb_log_error("Failed add DDF to category '"
[41ebc36]67 USBDIAG_CATEGORY "': %s.\n", str_error(rc));
[64d138b]68 goto err_bind;
69 }
[6c8a221c]70
[d23fab9]71 return EOK;
[64d138b]72
73err_bind:
74 ddf_fun_unbind(diag_dev->fun);
75err_create:
[b7b7898]76 usbdiag_dev_destroy(diag_dev);
[64d138b]77err:
78 return rc;
[d23fab9]79}
80
[7cba9f7]81static errno_t device_cleanup(usbdiag_dev_t *diag_dev)
[91173333]82{
83 /* TODO: Join some fibrils? */
84
85 /* Free memory. */
86 usbdiag_dev_destroy(diag_dev);
87 return EOK;
88}
89
[7cba9f7]90static errno_t device_remove(usb_device_t *dev)
[d23fab9]91{
[7cba9f7]92 errno_t rc;
[6c8a221c]93 usb_log_info("Removing device '%s'", usb_device_get_name(dev));
94
[b7b7898]95 usbdiag_dev_t *diag_dev = usb_device_to_usbdiag_dev(dev);
[6c8a221c]96
97 /* TODO: Make sure nothing is going on with the device. */
[64d138b]98
99 if ((rc = ddf_fun_unbind(diag_dev->fun))) {
[a1732929]100 usb_log_error("Failed to unbind DDF function: %s", str_error(rc));
[64d138b]101 goto err;
102 }
[6c8a221c]103
[91173333]104 usb_log_info("Device '%s' removed.", usb_device_get_name(dev));
105 return device_cleanup(diag_dev);
[64d138b]106
107err:
108 return rc;
[d23fab9]109}
110
[7cba9f7]111static errno_t device_gone(usb_device_t *dev)
[d23fab9]112{
[7cba9f7]113 errno_t rc;
[6c8a221c]114 usb_log_info("Device '%s' gone.", usb_device_get_name(dev));
115
[b7b7898]116 usbdiag_dev_t *diag_dev = usb_device_to_usbdiag_dev(dev);
[6c8a221c]117
118 /* TODO: Make sure nothing is going on with the device. */
119
[dfa1fc8]120 if ((rc = ddf_fun_unbind(diag_dev->fun))) {
[a1732929]121 usb_log_error("Failed to unbind DDF function: %s", str_error(rc));
[dfa1fc8]122 goto err;
123 }
[6c8a221c]124
[dfa1fc8]125 return device_cleanup(diag_dev);
126
127err:
128 return rc;
[d23fab9]129}
130
[7cba9f7]131static errno_t function_online(ddf_fun_t *fun)
[d23fab9]132{
133 return ddf_fun_online(fun);
134}
135
[7cba9f7]136static errno_t function_offline(ddf_fun_t *fun)
[d23fab9]137{
138 return ddf_fun_offline(fun);
139}
140
[8393c73b]141static const usb_endpoint_description_t burst_intr_in_ep = {
[47a9633]142 .transfer_type = USB_TRANSFER_INTERRUPT,
143 .direction = USB_DIRECTION_IN,
144 .interface_class = USB_CLASS_DIAGNOSTIC,
[02a7575]145 .interface_subclass = 0x00,
146 .interface_protocol = 0x01,
[47a9633]147 .flags = 0
148};
[8393c73b]149static const usb_endpoint_description_t burst_intr_out_ep = {
[47a9633]150 .transfer_type = USB_TRANSFER_INTERRUPT,
151 .direction = USB_DIRECTION_OUT,
152 .interface_class = USB_CLASS_DIAGNOSTIC,
[02a7575]153 .interface_subclass = 0x00,
154 .interface_protocol = 0x01,
[47a9633]155 .flags = 0
156};
[8393c73b]157static const usb_endpoint_description_t burst_bulk_in_ep = {
[47a9633]158 .transfer_type = USB_TRANSFER_BULK,
159 .direction = USB_DIRECTION_IN,
160 .interface_class = USB_CLASS_DIAGNOSTIC,
[02a7575]161 .interface_subclass = 0x00,
162 .interface_protocol = 0x01,
[47a9633]163 .flags = 0
164};
[8393c73b]165static const usb_endpoint_description_t burst_bulk_out_ep = {
[47a9633]166 .transfer_type = USB_TRANSFER_BULK,
167 .direction = USB_DIRECTION_OUT,
168 .interface_class = USB_CLASS_DIAGNOSTIC,
[02a7575]169 .interface_subclass = 0x00,
170 .interface_protocol = 0x01,
[47a9633]171 .flags = 0
172};
[8393c73b]173static const usb_endpoint_description_t burst_isoch_in_ep = {
[47a9633]174 .transfer_type = USB_TRANSFER_ISOCHRONOUS,
175 .direction = USB_DIRECTION_IN,
176 .interface_class = USB_CLASS_DIAGNOSTIC,
[02a7575]177 .interface_subclass = 0x00,
178 .interface_protocol = 0x01,
[47a9633]179 .flags = 0
180};
[8393c73b]181static const usb_endpoint_description_t burst_isoch_out_ep = {
182 .transfer_type = USB_TRANSFER_ISOCHRONOUS,
183 .direction = USB_DIRECTION_OUT,
184 .interface_class = USB_CLASS_DIAGNOSTIC,
185 .interface_subclass = 0x00,
186 .interface_protocol = 0x01,
187 .flags = 0
188};
189static const usb_endpoint_description_t data_intr_in_ep = {
190 .transfer_type = USB_TRANSFER_INTERRUPT,
191 .direction = USB_DIRECTION_IN,
192 .interface_class = USB_CLASS_DIAGNOSTIC,
193 .interface_subclass = 0x00,
194 .interface_protocol = 0x01,
195 .flags = 0
196};
197static const usb_endpoint_description_t data_intr_out_ep = {
198 .transfer_type = USB_TRANSFER_INTERRUPT,
199 .direction = USB_DIRECTION_OUT,
200 .interface_class = USB_CLASS_DIAGNOSTIC,
201 .interface_subclass = 0x00,
202 .interface_protocol = 0x01,
203 .flags = 0
204};
205static const usb_endpoint_description_t data_bulk_in_ep = {
206 .transfer_type = USB_TRANSFER_BULK,
207 .direction = USB_DIRECTION_IN,
208 .interface_class = USB_CLASS_DIAGNOSTIC,
209 .interface_subclass = 0x00,
210 .interface_protocol = 0x01,
211 .flags = 0
212};
213static const usb_endpoint_description_t data_bulk_out_ep = {
214 .transfer_type = USB_TRANSFER_BULK,
215 .direction = USB_DIRECTION_OUT,
216 .interface_class = USB_CLASS_DIAGNOSTIC,
217 .interface_subclass = 0x00,
218 .interface_protocol = 0x01,
219 .flags = 0
220};
221static const usb_endpoint_description_t data_isoch_in_ep = {
222 .transfer_type = USB_TRANSFER_ISOCHRONOUS,
223 .direction = USB_DIRECTION_IN,
224 .interface_class = USB_CLASS_DIAGNOSTIC,
225 .interface_subclass = 0x00,
226 .interface_protocol = 0x01,
227 .flags = 0
228};
229static const usb_endpoint_description_t data_isoch_out_ep = {
[47a9633]230 .transfer_type = USB_TRANSFER_ISOCHRONOUS,
231 .direction = USB_DIRECTION_OUT,
232 .interface_class = USB_CLASS_DIAGNOSTIC,
[02a7575]233 .interface_subclass = 0x00,
234 .interface_protocol = 0x01,
[47a9633]235 .flags = 0
236};
237
238static const usb_endpoint_description_t *diag_endpoints[] = {
[8393c73b]239 [USBDIAG_EP_BURST_INTR_IN] = &burst_intr_in_ep,
240 [USBDIAG_EP_BURST_INTR_OUT] = &burst_intr_out_ep,
241 [USBDIAG_EP_BURST_BULK_IN] = &burst_bulk_in_ep,
242 [USBDIAG_EP_BURST_BULK_OUT] = &burst_bulk_out_ep,
243 [USBDIAG_EP_BURST_ISOCH_IN] = &burst_isoch_in_ep,
244 [USBDIAG_EP_BURST_ISOCH_OUT] = &burst_isoch_out_ep,
245 [USBDIAG_EP_DATA_INTR_IN] = &data_intr_in_ep,
246 [USBDIAG_EP_DATA_INTR_OUT] = &data_intr_out_ep,
247 [USBDIAG_EP_DATA_BULK_IN] = &data_bulk_in_ep,
248 [USBDIAG_EP_DATA_BULK_OUT] = &data_bulk_out_ep,
249 [USBDIAG_EP_DATA_ISOCH_IN] = &data_isoch_in_ep,
250 [USBDIAG_EP_DATA_ISOCH_OUT] = &data_isoch_out_ep,
[47a9633]251 NULL
252};
253
[a8723748]254/** USB diagnostic driver ops. */
[b7e1458]255static const usb_driver_ops_t diag_driver_ops = {
[6c8a221c]256 .device_add = device_add,
[c54b898]257 .device_remove = device_remove,
[6c8a221c]258 .device_gone = device_gone,
259 .function_online = function_online,
260 .function_offline = function_offline
[d23fab9]261};
262
[a8723748]263/** USB diagnostic driver. */
[b7e1458]264static const usb_driver_t diag_driver = {
[d23fab9]265 .name = NAME,
[b7e1458]266 .ops = &diag_driver_ops,
[85bf12ba]267 .endpoints = &diag_endpoints[1] /* EPs are indexed from 1. */
[d23fab9]268};
269
270int main(int argc, char *argv[])
271{
[a8723748]272 printf(NAME ": USB diagnostic device driver.\n");
[d23fab9]273
274 log_init(NAME);
275
[b7e1458]276 return usb_driver_main(&diag_driver);
[d23fab9]277}
278
279/**
280 * @}
281 */
Note: See TracBrowser for help on using the repository browser.