added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / uwb / reset.c
blob70f8050221ff5efe5d0e733541f2465e63b41ee0
1 /*
2 * Ultra Wide Band
3 * UWB basic command support and radio reset
5 * Copyright (C) 2005-2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
23 * FIXME:
25 * - docs
27 * - Now we are serializing (using the uwb_dev->mutex) the command
28 * execution; it should be parallelized as much as possible some
29 * day.
31 #include <linux/kernel.h>
32 #include <linux/err.h>
34 #include "uwb-internal.h"
36 /**
37 * Command result codes (WUSB1.0[T8-69])
39 static
40 const char *__strerror[] = {
41 "success",
42 "failure",
43 "hardware failure",
44 "no more slots",
45 "beacon is too large",
46 "invalid parameter",
47 "unsupported power level",
48 "time out (wa) or invalid ie data (whci)",
49 "beacon size exceeded",
50 "cancelled",
51 "invalid state",
52 "invalid size",
53 "ack not recieved",
54 "no more asie notification",
58 /** Return a string matching the given error code */
59 const char *uwb_rc_strerror(unsigned code)
61 if (code == 255)
62 return "time out";
63 if (code >= ARRAY_SIZE(__strerror))
64 return "unknown error";
65 return __strerror[code];
68 int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name,
69 struct uwb_rccb *cmd, size_t cmd_size,
70 u8 expected_type, u16 expected_event,
71 uwb_rc_cmd_cb_f cb, void *arg)
73 struct device *dev = &rc->uwb_dev.dev;
74 struct uwb_rc_neh *neh;
75 int needtofree = 0;
76 int result;
78 uwb_dev_lock(&rc->uwb_dev); /* Protect against rc->priv being removed */
79 if (rc->priv == NULL) {
80 uwb_dev_unlock(&rc->uwb_dev);
81 return -ESHUTDOWN;
84 if (rc->filter_cmd) {
85 needtofree = rc->filter_cmd(rc, &cmd, &cmd_size);
86 if (needtofree < 0 && needtofree != -ENOANO) {
87 dev_err(dev, "%s: filter error: %d\n",
88 cmd_name, needtofree);
89 uwb_dev_unlock(&rc->uwb_dev);
90 return needtofree;
94 neh = uwb_rc_neh_add(rc, cmd, expected_type, expected_event, cb, arg);
95 if (IS_ERR(neh)) {
96 result = PTR_ERR(neh);
97 goto out;
100 result = rc->cmd(rc, cmd, cmd_size);
101 uwb_dev_unlock(&rc->uwb_dev);
102 if (result < 0)
103 uwb_rc_neh_rm(rc, neh);
104 else
105 uwb_rc_neh_arm(rc, neh);
106 uwb_rc_neh_put(neh);
107 out:
108 if (needtofree == 1)
109 kfree(cmd);
110 return result < 0 ? result : 0;
112 EXPORT_SYMBOL_GPL(uwb_rc_cmd_async);
114 struct uwb_rc_cmd_done_params {
115 struct completion completion;
116 struct uwb_rceb *reply;
117 ssize_t reply_size;
120 static void uwb_rc_cmd_done(struct uwb_rc *rc, void *arg,
121 struct uwb_rceb *reply, ssize_t reply_size)
123 struct uwb_rc_cmd_done_params *p = (struct uwb_rc_cmd_done_params *)arg;
125 if (reply_size > 0) {
126 if (p->reply)
127 reply_size = min(p->reply_size, reply_size);
128 else
129 p->reply = kmalloc(reply_size, GFP_ATOMIC);
131 if (p->reply)
132 memcpy(p->reply, reply, reply_size);
133 else
134 reply_size = -ENOMEM;
136 p->reply_size = reply_size;
137 complete(&p->completion);
142 * Generic function for issuing commands to the Radio Control Interface
144 * @rc: UWB Radio Control descriptor
145 * @cmd_name: Name of the command being issued (for error messages)
146 * @cmd: Pointer to rccb structure containing the command;
147 * normally you embed this structure as the first member of
148 * the full command structure.
149 * @cmd_size: Size of the whole command buffer pointed to by @cmd.
150 * @reply: Pointer to where to store the reply
151 * @reply_size: @reply's size
152 * @expected_type: Expected type in the return event
153 * @expected_event: Expected event code in the return event
154 * @preply: Here a pointer to where the event data is received will
155 * be stored. Once done with the data, free with kfree().
157 * This function is generic; it works for commands that return a fixed
158 * and known size or for commands that return a variable amount of data.
160 * If a buffer is provided, that is used, although it could be chopped
161 * to the maximum size of the buffer. If the buffer is NULL, then one
162 * be allocated in *preply with the whole contents of the reply.
164 * @rc needs to be referenced
166 static
167 ssize_t __uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
168 struct uwb_rccb *cmd, size_t cmd_size,
169 struct uwb_rceb *reply, size_t reply_size,
170 u8 expected_type, u16 expected_event,
171 struct uwb_rceb **preply)
173 ssize_t result = 0;
174 struct device *dev = &rc->uwb_dev.dev;
175 struct uwb_rc_cmd_done_params params;
177 init_completion(&params.completion);
178 params.reply = reply;
179 params.reply_size = reply_size;
181 result = uwb_rc_cmd_async(rc, cmd_name, cmd, cmd_size,
182 expected_type, expected_event,
183 uwb_rc_cmd_done, &params);
184 if (result)
185 return result;
187 wait_for_completion(&params.completion);
189 if (preply)
190 *preply = params.reply;
192 if (params.reply_size < 0)
193 dev_err(dev, "%s: confirmation event 0x%02x/%04x/%02x "
194 "reception failed: %d\n", cmd_name,
195 expected_type, expected_event, cmd->bCommandContext,
196 (int)params.reply_size);
197 return params.reply_size;
202 * Generic function for issuing commands to the Radio Control Interface
204 * @rc: UWB Radio Control descriptor
205 * @cmd_name: Name of the command being issued (for error messages)
206 * @cmd: Pointer to rccb structure containing the command;
207 * normally you embed this structure as the first member of
208 * the full command structure.
209 * @cmd_size: Size of the whole command buffer pointed to by @cmd.
210 * @reply: Pointer to the beginning of the confirmation event
211 * buffer. Normally bigger than an 'struct hwarc_rceb'.
212 * You need to fill out reply->bEventType and reply->wEvent (in
213 * cpu order) as the function will use them to verify the
214 * confirmation event.
215 * @reply_size: Size of the reply buffer
217 * The function checks that the length returned in the reply is at
218 * least as big as @reply_size; if not, it will be deemed an error and
219 * -EIO returned.
221 * @rc needs to be referenced
223 ssize_t uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
224 struct uwb_rccb *cmd, size_t cmd_size,
225 struct uwb_rceb *reply, size_t reply_size)
227 struct device *dev = &rc->uwb_dev.dev;
228 ssize_t result;
230 result = __uwb_rc_cmd(rc, cmd_name,
231 cmd, cmd_size, reply, reply_size,
232 reply->bEventType, reply->wEvent, NULL);
234 if (result > 0 && result < reply_size) {
235 dev_err(dev, "%s: not enough data returned for decoding reply "
236 "(%zu bytes received vs at least %zu needed)\n",
237 cmd_name, result, reply_size);
238 result = -EIO;
240 return result;
242 EXPORT_SYMBOL_GPL(uwb_rc_cmd);
246 * Generic function for issuing commands to the Radio Control
247 * Interface that return an unknown amount of data
249 * @rc: UWB Radio Control descriptor
250 * @cmd_name: Name of the command being issued (for error messages)
251 * @cmd: Pointer to rccb structure containing the command;
252 * normally you embed this structure as the first member of
253 * the full command structure.
254 * @cmd_size: Size of the whole command buffer pointed to by @cmd.
255 * @expected_type: Expected type in the return event
256 * @expected_event: Expected event code in the return event
257 * @preply: Here a pointer to where the event data is received will
258 * be stored. Once done with the data, free with kfree().
260 * The function checks that the length returned in the reply is at
261 * least as big as a 'struct uwb_rceb *'; if not, it will be deemed an
262 * error and -EIO returned.
264 * @rc needs to be referenced
266 ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name,
267 struct uwb_rccb *cmd, size_t cmd_size,
268 u8 expected_type, u16 expected_event,
269 struct uwb_rceb **preply)
271 return __uwb_rc_cmd(rc, cmd_name, cmd, cmd_size, NULL, 0,
272 expected_type, expected_event, preply);
274 EXPORT_SYMBOL_GPL(uwb_rc_vcmd);
278 * Reset a UWB Host Controller (and all radio settings)
280 * @rc: Host Controller descriptor
281 * @returns: 0 if ok, < 0 errno code on error
283 * We put the command on kmalloc'ed memory as some arches cannot do
284 * USB from the stack. The reply event is copied from an stage buffer,
285 * so it can be in the stack. See WUSB1.0[8.6.2.4] for more details.
287 int uwb_rc_reset(struct uwb_rc *rc)
289 int result = -ENOMEM;
290 struct uwb_rc_evt_confirm reply;
291 struct uwb_rccb *cmd;
292 size_t cmd_size = sizeof(*cmd);
294 mutex_lock(&rc->uwb_dev.mutex);
295 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
296 if (cmd == NULL)
297 goto error_kzalloc;
298 cmd->bCommandType = UWB_RC_CET_GENERAL;
299 cmd->wCommand = cpu_to_le16(UWB_RC_CMD_RESET);
300 reply.rceb.bEventType = UWB_RC_CET_GENERAL;
301 reply.rceb.wEvent = UWB_RC_CMD_RESET;
302 result = uwb_rc_cmd(rc, "RESET", cmd, cmd_size,
303 &reply.rceb, sizeof(reply));
304 if (result < 0)
305 goto error_cmd;
306 if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
307 dev_err(&rc->uwb_dev.dev,
308 "RESET: command execution failed: %s (%d)\n",
309 uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
310 result = -EIO;
312 error_cmd:
313 kfree(cmd);
314 error_kzalloc:
315 mutex_unlock(&rc->uwb_dev.mutex);
316 return result;
319 int uwbd_msg_handle_reset(struct uwb_event *evt)
321 struct uwb_rc *rc = evt->rc;
322 int ret;
324 dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
325 ret = rc->reset(rc);
326 if (ret) {
327 dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
328 goto error;
330 return 0;
331 error:
332 /* Nothing can be done except try the reset again. */
333 uwb_rc_reset_all(rc);
334 return ret;
338 * uwb_rc_reset_all - request a reset of the radio controller and PALs
339 * @rc: the radio controller of the hardware device to be reset.
341 * The full hardware reset of the radio controller and all the PALs
342 * will be scheduled.
344 void uwb_rc_reset_all(struct uwb_rc *rc)
346 struct uwb_event *evt;
348 evt = kzalloc(sizeof(struct uwb_event), GFP_ATOMIC);
349 if (unlikely(evt == NULL))
350 return;
352 evt->rc = __uwb_rc_get(rc); /* will be put by uwbd's uwbd_event_handle() */
353 evt->ts_jiffies = jiffies;
354 evt->type = UWB_EVT_TYPE_MSG;
355 evt->message = UWB_EVT_MSG_RESET;
357 uwbd_event_queue(evt);
359 EXPORT_SYMBOL_GPL(uwb_rc_reset_all);
361 void uwb_rc_pre_reset(struct uwb_rc *rc)
363 rc->stop(rc);
364 uwbd_flush(rc);
366 uwb_radio_reset_state(rc);
367 uwb_rsv_remove_all(rc);
369 EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
371 void uwb_rc_post_reset(struct uwb_rc *rc)
373 int ret;
375 ret = rc->start(rc);
376 if (ret)
377 goto error;
378 ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr);
379 if (ret)
380 goto error;
381 ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr);
382 if (ret)
383 goto error;
384 return;
385 error:
386 /* Nothing can be done except try the reset again. */
387 uwb_rc_reset_all(rc);
389 EXPORT_SYMBOL_GPL(uwb_rc_post_reset);