1/*****************************************************************************/ 2/* 3 * auerchain.c -- Auerswald PBX/System Telephone chained urb support. 4 * 5 * Copyright (C) 2002 Wolfgang M�es (wolfgang@iksw-muees.de) 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 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., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 /*****************************************************************************/ 22 23#undef DEBUG /* include debug macros until it's done */ 24#include <linux/usb.h> 25#include "auerchain.h" 26#include <linux/slab.h> 27 28/* completion function for chained urbs */ 29static void auerchain_complete(struct urb *urb) 30{ 31 unsigned long flags; 32 int result; 33 34 /* get pointer to element and to chain */ 35 struct auerchainelement *acep = 36 (struct auerchainelement *) urb->context; 37 struct auerchain *acp = acep->chain; 38 39 /* restore original entries in urb */ 40 urb->context = acep->context; 41 urb->complete = acep->complete; 42 43 dbg("auerchain_complete called"); 44 45 /* call original completion function 46 NOTE: this function may lead to more urbs submitted into the chain. 47 (no chain lock at calling complete()!) 48 acp->active != NULL is protecting us against recursion. */ 49 urb->complete(urb); 50 51 /* detach element from chain data structure */ 52 spin_lock_irqsave(&acp->lock, flags); 53 if (acp->active != acep) /* paranoia debug check */ 54 dbg("auerchain_complete: completion on non-active element called!"); 55 else 56 acp->active = NULL; 57 58 /* add the used chain element to the list of free elements */ 59 list_add_tail(&acep->list, &acp->free_list); 60 acep = NULL; 61 62 /* is there a new element waiting in the chain? */ 63 if (!acp->active && !list_empty(&acp->waiting_list)) { 64 /* yes: get the entry */ 65 struct list_head *tmp = acp->waiting_list.next; 66 list_del(tmp); 67 acep = list_entry(tmp, struct auerchainelement, list); 68 acp->active = acep; 69 } 70 spin_unlock_irqrestore(&acp->lock, flags); 71 72 /* submit the new urb */ 73 if (acep) { 74 urb = acep->urbp; 75 dbg("auerchain_complete: submitting next urb from chain"); 76 urb->status = 0; /* needed! */ 77 result = usb_submit_urb(urb); 78 79 /* check for submit errors */ 80 if (result) { 81 urb->status = result; 82 dbg("auerchain_complete: usb_submit_urb with error code %d", result); 83 /* and do error handling via *this* completion function (recursive) */ 84 auerchain_complete(urb); 85 } 86 } else { 87 /* simple return without submitting a new urb. 88 The empty chain is detected with acp->active == NULL. */ 89 }; 90} 91 92/* submit function for chained urbs 93 this function may be called from completion context or from user space! 94 early = 1 -> submit in front of chain 95*/ 96int auerchain_submit_urb_list(struct auerchain *acp, struct urb *urb, 97 int early) 98{ 99 int result; 100 unsigned long flags; 101 struct auerchainelement *acep = NULL; 102 103 dbg("auerchain_submit_urb called"); 104 105 /* try to get a chain element */ 106 spin_lock_irqsave(&acp->lock, flags); 107 if (!list_empty(&acp->free_list)) { 108 /* yes: get the entry */ 109 struct list_head *tmp = acp->free_list.next; 110 list_del(tmp); 111 acep = list_entry(tmp, struct auerchainelement, list); 112 } 113 spin_unlock_irqrestore(&acp->lock, flags); 114 115 /* if no chain element available: return with error */ 116 if (!acep) { 117 return -ENOMEM; 118 } 119 120 /* fill in the new chain element values */ 121 acep->chain = acp; 122 acep->context = urb->context; 123 acep->complete = urb->complete; 124 acep->urbp = urb; 125 INIT_LIST_HEAD(&acep->list); 126 127 /* modify urb */ 128 urb->context = acep; 129 urb->complete = auerchain_complete; 130 urb->status = -EINPROGRESS; /* usb_submit_urb does this, too */ 131 132 /* add element to chain - or start it immediately */ 133 spin_lock_irqsave(&acp->lock, flags); 134 if (acp->active) { 135 /* there is traffic in the chain, simple add element to chain */ 136 if (early) { 137 dbg("adding new urb to head of chain"); 138 list_add(&acep->list, &acp->waiting_list); 139 } else { 140 dbg("adding new urb to end of chain"); 141 list_add_tail(&acep->list, &acp->waiting_list); 142 } 143 acep = NULL; 144 } else { 145 /* the chain is empty. Prepare restart */ 146 acp->active = acep; 147 } 148 /* Spin has to be removed before usb_submit_urb! */ 149 spin_unlock_irqrestore(&acp->lock, flags); 150 151 /* Submit urb if immediate restart */ 152 if (acep) { 153 dbg("submitting urb immediate"); 154 urb->status = 0; /* needed! */ 155 result = usb_submit_urb(urb); 156 /* check for submit errors */ 157 if (result) { 158 urb->status = result; 159 dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result); 160 /* and do error handling via completion function */ 161 auerchain_complete(urb); 162 } 163 } 164 165 return 0; 166} 167 168/* submit function for chained urbs 169 this function may be called from completion context or from user space! 170*/ 171int auerchain_submit_urb(struct auerchain *acp, struct urb *urb) 172{ 173 return auerchain_submit_urb_list(acp, urb, 0); 174} 175 176/* cancel an urb which is submitted to the chain 177 the result is 0 if the urb is cancelled, or -EINPROGRESS if 178 USB_ASYNC_UNLINK is set and the function is successfully started. 179*/ 180int auerchain_unlink_urb(struct auerchain *acp, struct urb *urb) 181{ 182 unsigned long flags; 183 struct urb *urbp; 184 struct auerchainelement *acep; 185 struct list_head *tmp; 186 187 dbg("auerchain_unlink_urb called"); 188 189 /* search the chain of waiting elements */ 190 spin_lock_irqsave(&acp->lock, flags); 191 list_for_each(tmp, &acp->waiting_list) { 192 acep = list_entry(tmp, struct auerchainelement, list); 193 if (acep->urbp == urb) { 194 list_del(tmp); 195 urb->context = acep->context; 196 urb->complete = acep->complete; 197 list_add_tail(&acep->list, &acp->free_list); 198 spin_unlock_irqrestore(&acp->lock, flags); 199 dbg("unlink waiting urb"); 200 urb->status = -ENOENT; 201 urb->complete(urb); 202 return 0; 203 } 204 } 205 /* not found. */ 206 spin_unlock_irqrestore(&acp->lock, flags); 207 208 /* get the active urb */ 209 acep = acp->active; 210 if (acep) { 211 urbp = acep->urbp; 212 213 /* check if we have to cancel the active urb */ 214 if (urbp == urb) { 215 /* note that there is a race condition between the check above 216 and the unlink() call because of no lock. This race is harmless, 217 because the usb module will detect the unlink() after completion. 218 We can't use the acp->lock here because the completion function 219 wants to grab it. 220 */ 221 dbg("unlink active urb"); 222 return usb_unlink_urb(urbp); 223 } 224 } 225 226 /* not found anyway 227 ... is some kind of success 228 */ 229 dbg("urb to unlink not found in chain"); 230 return 0; 231} 232 233/* cancel all urbs which are in the chain. 234 this function must not be called from interrupt or completion handler. 235*/ 236void auerchain_unlink_all(struct auerchain *acp) 237{ 238 unsigned long flags; 239 struct urb *urbp; 240 struct auerchainelement *acep; 241 242 dbg("auerchain_unlink_all called"); 243 244 /* clear the chain of waiting elements */ 245 spin_lock_irqsave(&acp->lock, flags); 246 while (!list_empty(&acp->waiting_list)) { 247 /* get the next entry */ 248 struct list_head *tmp = acp->waiting_list.next; 249 list_del(tmp); 250 acep = list_entry(tmp, struct auerchainelement, list); 251 urbp = acep->urbp; 252 urbp->context = acep->context; 253 urbp->complete = acep->complete; 254 list_add_tail(&acep->list, &acp->free_list); 255 spin_unlock_irqrestore(&acp->lock, flags); 256 dbg("unlink waiting urb"); 257 urbp->status = -ENOENT; 258 urbp->complete(urbp); 259 spin_lock_irqsave(&acp->lock, flags); 260 } 261 spin_unlock_irqrestore(&acp->lock, flags); 262 263 /* clear the active urb */ 264 acep = acp->active; 265 if (acep) { 266 urbp = acep->urbp; 267 urbp->transfer_flags &= ~USB_ASYNC_UNLINK; 268 dbg("unlink active urb"); 269 usb_unlink_urb(urbp); 270 } 271} 272 273 274/* free the chain. 275 this function must not be called from interrupt or completion handler. 276*/ 277void auerchain_free(struct auerchain *acp) 278{ 279 unsigned long flags; 280 struct auerchainelement *acep; 281 282 dbg("auerchain_free called"); 283 284 /* first, cancel all pending urbs */ 285 auerchain_unlink_all(acp); 286 287 /* free the elements */ 288 spin_lock_irqsave(&acp->lock, flags); 289 while (!list_empty(&acp->free_list)) { 290 /* get the next entry */ 291 struct list_head *tmp = acp->free_list.next; 292 list_del(tmp); 293 spin_unlock_irqrestore(&acp->lock, flags); 294 acep = list_entry(tmp, struct auerchainelement, list); 295 kfree(acep); 296 spin_lock_irqsave(&acp->lock, flags); 297 } 298 spin_unlock_irqrestore(&acp->lock, flags); 299} 300 301 302/* Init the chain control structure */ 303void auerchain_init(struct auerchain *acp) 304{ 305 /* init the chain data structure */ 306 acp->active = NULL; 307 spin_lock_init(&acp->lock); 308 INIT_LIST_HEAD(&acp->waiting_list); 309 INIT_LIST_HEAD(&acp->free_list); 310} 311 312/* setup a chain. 313 It is assumed that there is no concurrency while setting up the chain 314 requirement: auerchain_init() 315*/ 316int auerchain_setup(struct auerchain *acp, unsigned int numElements) 317{ 318 struct auerchainelement *acep; 319 320 dbg("auerchain_setup called with %d elements", numElements); 321 322 /* fill the list of free elements */ 323 for (; numElements; numElements--) { 324 acep = 325 (struct auerchainelement *) 326 kmalloc(sizeof(struct auerchainelement), GFP_KERNEL); 327 if (!acep) 328 goto ac_fail; 329 memset(acep, 0, sizeof(struct auerchainelement)); 330 INIT_LIST_HEAD(&acep->list); 331 list_add_tail(&acep->list, &acp->free_list); 332 } 333 return 0; 334 335 ac_fail: /* free the elements */ 336 while (!list_empty(&acp->free_list)) { 337 /* get the next entry */ 338 struct list_head *tmp = acp->free_list.next; 339 list_del(tmp); 340 acep = list_entry(tmp, struct auerchainelement, list); 341 kfree(acep); 342 } 343 return -ENOMEM; 344} 345 346 347/* completion handler for synchronous chained URBs */ 348static void auerchain_blocking_completion(struct urb *urb) 349{ 350 struct auerchain_chs *pchs = (struct auerchain_chs *) urb->context; 351 pchs->done = 1; 352 wmb(); 353 wake_up(&pchs->wqh); 354} 355 356 357/* Starts chained urb and waits for completion or timeout */ 358static int auerchain_start_wait_urb(struct auerchain *acp, struct urb *urb, 359 int timeout, int *actual_length) 360{ 361 DECLARE_WAITQUEUE(wait, current); 362 struct auerchain_chs chs; 363 int status; 364 365 dbg("auerchain_start_wait_urb called"); 366 init_waitqueue_head(&chs.wqh); 367 chs.done = 0; 368 369 set_current_state(TASK_UNINTERRUPTIBLE); 370 add_wait_queue(&chs.wqh, &wait); 371 urb->context = &chs; 372 status = auerchain_submit_urb(acp, urb); 373 if (status) { 374 /* something went wrong */ 375 set_current_state(TASK_RUNNING); 376 remove_wait_queue(&chs.wqh, &wait); 377 return status; 378 } 379 380 while (timeout && !chs.done) { 381 timeout = schedule_timeout(timeout); 382 set_current_state(TASK_UNINTERRUPTIBLE); 383 rmb(); 384 } 385 386 set_current_state(TASK_RUNNING); 387 remove_wait_queue(&chs.wqh, &wait); 388 389 if (!timeout && !chs.done) { 390 if (urb->status != -EINPROGRESS) { /* No callback?!! */ 391 dbg("auerchain_start_wait_urb: raced timeout"); 392 status = urb->status; 393 } else { 394 dbg("auerchain_start_wait_urb: timeout"); 395 auerchain_unlink_urb(acp, urb); /* remove urb safely */ 396 status = -ETIMEDOUT; 397 } 398 } else 399 status = urb->status; 400 401 if (actual_length) 402 *actual_length = urb->actual_length; 403 404 return status; 405} 406 407 408/* auerchain_control_msg - Builds a control urb, sends it off and waits for completion 409 acp: pointer to the auerchain 410 dev: pointer to the usb device to send the message to 411 pipe: endpoint "pipe" to send the message to 412 request: USB message request value 413 requesttype: USB message request type value 414 value: USB message value 415 index: USB message index value 416 data: pointer to the data to send 417 size: length in bytes of the data to send 418 timeout: time to wait for the message to complete before timing out (if 0 the wait is forever) 419 420 This function sends a simple control message to a specified endpoint 421 and waits for the message to complete, or timeout. 422 423 If successful, it returns the transfered length, othwise a negative error number. 424 425 Don't use this function from within an interrupt context, like a 426 bottom half handler. If you need a asyncronous message, or need to send 427 a message from within interrupt context, use auerchain_submit_urb() 428*/ 429int auerchain_control_msg(struct auerchain *acp, struct usb_device *dev, 430 unsigned int pipe, __u8 request, 431 __u8 requesttype, __u16 value, __u16 index, 432 void *data, __u16 size, int timeout) 433{ 434 int ret; 435 struct usb_ctrlrequest *dr; 436 struct urb *urb; 437 int length; 438 439 dbg("auerchain_control_msg"); 440 dr = (struct usb_ctrlrequest *) 441 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 442 if (!dr) 443 return -ENOMEM; 444 urb = usb_alloc_urb(0); 445 if (!urb) { 446 kfree(dr); 447 return -ENOMEM; 448 } 449 450 dr->bRequestType = requesttype; 451 dr->bRequest = request; 452 dr->wValue = cpu_to_le16(value); 453 dr->wIndex = cpu_to_le16(index); 454 dr->wLength = cpu_to_le16(size); 455 456 FILL_CONTROL_URB(urb, dev, pipe, (unsigned char *) dr, data, size, /* build urb */ 457 (usb_complete_t) auerchain_blocking_completion, 458 0); 459 ret = auerchain_start_wait_urb(acp, urb, timeout, &length); 460 461 usb_free_urb(urb); 462 kfree(dr); 463 464 if (ret < 0) 465 return ret; 466 else 467 return length; 468} 469