source: mainline/uspace/drv/char/pc-lpt/main.c@ ca22536

Last change on this file since ca22536 was b9cc81c6, checked in by Jiri Svoboda <jiri@…>, 5 months ago

Implement quiesce in NS8250 and PC-LPT.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2025 Jiri Svoboda
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
29/** @addtogroup uspace_drv_pc_lpt
30 * @{
31 */
32/** @file PC parallel port driver
33 */
34
35#include <ddf/driver.h>
36#include <ddf/log.h>
37#include <device/hw_res_parsed.h>
38#include <errno.h>
39#include <stdio.h>
40
41#include "pc-lpt.h"
42
43#define NAME "pc-lpt"
44
45static errno_t pc_lpt_dev_add(ddf_dev_t *dev);
46static errno_t pc_lpt_dev_remove(ddf_dev_t *dev);
47static errno_t pc_lpt_dev_gone(ddf_dev_t *dev);
48static errno_t pc_lpt_dev_quiesce(ddf_dev_t *dev);
49static errno_t pc_lpt_fun_online(ddf_fun_t *fun);
50static errno_t pc_lpt_fun_offline(ddf_fun_t *fun);
51
52static driver_ops_t driver_ops = {
53 .dev_add = pc_lpt_dev_add,
54 .dev_remove = pc_lpt_dev_remove,
55 .dev_gone = pc_lpt_dev_gone,
56 .dev_quiesce = pc_lpt_dev_quiesce,
57 .fun_online = pc_lpt_fun_online,
58 .fun_offline = pc_lpt_fun_offline
59};
60
61static driver_t pc_lpt_driver = {
62 .name = NAME,
63 .driver_ops = &driver_ops
64};
65
66static errno_t pc_lpt_get_res(ddf_dev_t *dev, pc_lpt_res_t *res)
67{
68 async_sess_t *parent_sess;
69 hw_res_list_parsed_t hw_res;
70 errno_t rc;
71
72 parent_sess = ddf_dev_parent_sess_get(dev);
73 if (parent_sess == NULL)
74 return ENOMEM;
75
76 hw_res_list_parsed_init(&hw_res);
77 rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
78 if (rc != EOK)
79 return rc;
80
81 if (hw_res.io_ranges.count != 1) {
82 rc = EINVAL;
83 goto error;
84 }
85
86 res->base = RNGABS(hw_res.io_ranges.ranges[0]);
87
88 if (hw_res.irqs.count != 1) {
89 rc = EINVAL;
90 goto error;
91 }
92
93 res->irq = hw_res.irqs.irqs[0];
94
95 return EOK;
96error:
97 hw_res_list_parsed_clean(&hw_res);
98 return rc;
99}
100
101static errno_t pc_lpt_dev_add(ddf_dev_t *dev)
102{
103 pc_lpt_t *pc_lpt;
104 pc_lpt_res_t res;
105 errno_t rc;
106
107 ddf_msg(LVL_DEBUG, "pc_lpt_dev_add(%p)", dev);
108
109 pc_lpt = ddf_dev_data_alloc(dev, sizeof(pc_lpt_t));
110 if (pc_lpt == NULL) {
111 ddf_msg(LVL_ERROR, "Failed allocating soft state.");
112 return ENOMEM;
113 }
114
115 pc_lpt->dev = dev;
116
117 rc = pc_lpt_get_res(dev, &res);
118 if (rc != EOK) {
119 ddf_msg(LVL_ERROR, "Failed getting hardware resource list.");
120 return EIO;
121 }
122
123 return pc_lpt_add(pc_lpt, &res);
124}
125
126static errno_t pc_lpt_dev_remove(ddf_dev_t *dev)
127{
128 pc_lpt_t *pc_lpt = (pc_lpt_t *)ddf_dev_data_get(dev);
129
130 ddf_msg(LVL_DEBUG, "pc_lpt_dev_remove(%p)", dev);
131
132 return pc_lpt_remove(pc_lpt);
133}
134
135static errno_t pc_lpt_dev_gone(ddf_dev_t *dev)
136{
137 pc_lpt_t *pc_lpt = (pc_lpt_t *)ddf_dev_data_get(dev);
138
139 ddf_msg(LVL_DEBUG, "pc_lpt_dev_gone(%p)", dev);
140
141 return pc_lpt_gone(pc_lpt);
142}
143
144static errno_t pc_lpt_dev_quiesce(ddf_dev_t *dev)
145{
146 pc_lpt_t *pc_lpt = (pc_lpt_t *)ddf_dev_data_get(dev);
147
148 ddf_msg(LVL_DEBUG, "pc_lpt_dev_quiesce(%p)", dev);
149
150 pc_lpt_quiesce(pc_lpt);
151 return EOK;
152}
153
154static errno_t pc_lpt_fun_online(ddf_fun_t *fun)
155{
156 ddf_msg(LVL_DEBUG, "pc_lpt_fun_online()");
157 return ddf_fun_online(fun);
158}
159
160static errno_t pc_lpt_fun_offline(ddf_fun_t *fun)
161{
162 ddf_msg(LVL_DEBUG, "pc_lpt_fun_offline()");
163 return ddf_fun_offline(fun);
164}
165
166int main(int argc, char *argv[])
167{
168 printf(NAME ": PC parallel port driver\n");
169 ddf_log_init(NAME);
170 return ddf_driver_main(&pc_lpt_driver);
171}
172
173/** @}
174 */
Note: See TracBrowser for help on using the repository browser.