ACPI: Revert conflicting workaround for BIOS w/ mangled PRT entries
[linux-2.6] / drivers / uwb / reset.c
1 /*
2  * Ultra Wide Band
3  * UWB basic command support and radio reset
4  *
5  * Copyright (C) 2005-2006 Intel Corporation
6  * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7  *
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.
11  *
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.
16  *
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.
21  *
22  *
23  * FIXME:
24  *
25  *  - docs
26  *
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.
30  */
31 #include <linux/kernel.h>
32 #include <linux/err.h>
33
34 #include "uwb-internal.h"
35
36 /**
37  * Command result codes (WUSB1.0[T8-69])
38  */
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",
55 };
56
57
58 /** Return a string matching the given error code */
59 const char *uwb_rc_strerror(unsigned code)
60 {
61         if (code == 255)
62                 return "time out";
63         if (code >= ARRAY_SIZE(__strerror))
64                 return "unknown error";
65         return __strerror[code];
66 }
67
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)
72 {
73         struct device *dev = &rc->uwb_dev.dev;
74         struct uwb_rc_neh *neh;
75         int needtofree = 0;
76         int result;
77
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;
82         }
83
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;
91                 }
92         }
93
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;
98         }
99
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;
111 }
112 EXPORT_SYMBOL_GPL(uwb_rc_cmd_async);
113
114 struct uwb_rc_cmd_done_params {
115         struct completion completion;
116         struct uwb_rceb *reply;
117         ssize_t reply_size;
118 };
119
120 static void uwb_rc_cmd_done(struct uwb_rc *rc, void *arg,
121                             struct uwb_rceb *reply, ssize_t reply_size)
122 {
123         struct uwb_rc_cmd_done_params *p = (struct uwb_rc_cmd_done_params *)arg;
124
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);
130
131                 if (p->reply)
132                         memcpy(p->reply, reply, reply_size);
133                 else
134                         reply_size = -ENOMEM;
135         }
136         p->reply_size = reply_size;
137         complete(&p->completion);
138 }
139
140
141 /**
142  * Generic function for issuing commands to the Radio Control Interface
143  *
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().
156  *
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.
159  *
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.
163  *
164  * @rc needs to be referenced
165  */
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)
172 {
173         ssize_t result = 0;
174         struct device *dev = &rc->uwb_dev.dev;
175         struct uwb_rc_cmd_done_params params;
176
177         init_completion(&params.completion);
178         params.reply = reply;
179         params.reply_size = reply_size;
180
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;
186
187         wait_for_completion(&params.completion);
188
189         if (preply)
190                 *preply = params.reply;
191
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;
198 }
199
200
201 /**
202  * Generic function for issuing commands to the Radio Control Interface
203  *
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
216  *
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.
220  *
221  * @rc needs to be referenced
222  */
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)
226 {
227         struct device *dev = &rc->uwb_dev.dev;
228         ssize_t result;
229
230         result = __uwb_rc_cmd(rc, cmd_name,
231                               cmd, cmd_size, reply, reply_size,
232                               reply->bEventType, reply->wEvent, NULL);
233
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;
239         }
240         return result;
241 }
242 EXPORT_SYMBOL_GPL(uwb_rc_cmd);
243
244
245 /**
246  * Generic function for issuing commands to the Radio Control
247  * Interface that return an unknown amount of data
248  *
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().
259  *
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.
263  *
264  * @rc needs to be referenced
265  */
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)
270 {
271         return __uwb_rc_cmd(rc, cmd_name, cmd, cmd_size, NULL, 0,
272                             expected_type, expected_event, preply);
273 }
274 EXPORT_SYMBOL_GPL(uwb_rc_vcmd);
275
276
277 /**
278  * Reset a UWB Host Controller (and all radio settings)
279  *
280  * @rc:      Host Controller descriptor
281  * @returns: 0 if ok, < 0 errno code on error
282  *
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.
286  */
287 int uwb_rc_reset(struct uwb_rc *rc)
288 {
289         int result = -ENOMEM;
290         struct uwb_rc_evt_confirm reply;
291         struct uwb_rccb *cmd;
292         size_t cmd_size = sizeof(*cmd);
293
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;
311         }
312 error_cmd:
313         kfree(cmd);
314 error_kzalloc:
315         mutex_unlock(&rc->uwb_dev.mutex);
316         return result;
317 }
318
319 int uwbd_msg_handle_reset(struct uwb_event *evt)
320 {
321         struct uwb_rc *rc = evt->rc;
322         int ret;
323
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;
329         }
330         return 0;
331 error:
332         /* Nothing can be done except try the reset again. */
333         uwb_rc_reset_all(rc);
334         return ret;
335 }
336
337 /**
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.
340  *
341  * The full hardware reset of the radio controller and all the PALs
342  * will be scheduled.
343  */
344 void uwb_rc_reset_all(struct uwb_rc *rc)
345 {
346         struct uwb_event *evt;
347
348         evt = kzalloc(sizeof(struct uwb_event), GFP_ATOMIC);
349         if (unlikely(evt == NULL))
350                 return;
351
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;
356
357         uwbd_event_queue(evt);
358 }
359 EXPORT_SYMBOL_GPL(uwb_rc_reset_all);
360
361 void uwb_rc_pre_reset(struct uwb_rc *rc)
362 {
363         rc->stop(rc);
364         uwbd_flush(rc);
365
366         uwb_radio_reset_state(rc);
367         uwb_rsv_remove_all(rc);
368 }
369 EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
370
371 void uwb_rc_post_reset(struct uwb_rc *rc)
372 {
373         int ret;
374
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);
388 }
389 EXPORT_SYMBOL_GPL(uwb_rc_post_reset);