340 { |
340 { |
341 ec_master_t *master; |
341 ec_master_t *master; |
342 char str[50]; // FIXME |
342 char str[50]; // FIXME |
343 |
343 |
344 list_for_each_entry(master, &masters, list) { |
344 list_for_each_entry(master, &masters, list) { |
345 if (down_interruptible(&master->device_sem)) { |
|
346 EC_ERR("Interrupted while waiting for device semaphore!\n"); |
|
347 goto out_return; |
|
348 } |
|
349 |
|
350 if (ec_device_id_check(master->main_device_id, net_dev, |
345 if (ec_device_id_check(master->main_device_id, net_dev, |
351 driver_name, device_index)) { |
346 driver_name, device_index)) { |
352 |
|
353 ec_device_id_print(master->main_device_id, str); |
347 ec_device_id_print(master->main_device_id, str); |
354 EC_INFO("Accepting device %s for master %u.\n", |
348 EC_INFO("Accepting device %s for master %u.\n", |
355 str, master->index); |
349 str, master->index); |
356 |
350 |
357 if (master->device) { |
351 if (down_interruptible(&master->device_sem)) { |
358 EC_ERR("Master %u already has a device.\n", master->index); |
352 EC_ERR("Interrupted while waiting for device semaphore!\n"); |
359 goto out_up; |
353 return -1; |
|
354 } |
|
355 |
|
356 if (master->main_device.dev) { |
|
357 EC_ERR("Master %u already has a device attached.\n", |
|
358 master->index); |
|
359 up(&master->device_sem); |
|
360 return -1; |
360 } |
361 } |
361 |
362 |
362 if (!(master->device = (ec_device_t *) |
363 ec_device_attach(&master->main_device, net_dev, poll, module); |
363 kmalloc(sizeof(ec_device_t), GFP_KERNEL))) { |
|
364 EC_ERR("Failed to allocate device!\n"); |
|
365 goto out_up; |
|
366 } |
|
367 |
|
368 if (ec_device_init(master->device, master, |
|
369 net_dev, poll, module)) { |
|
370 EC_ERR("Failed to init device!\n"); |
|
371 goto out_free; |
|
372 } |
|
373 |
|
374 up(&master->device_sem); |
364 up(&master->device_sem); |
|
365 |
375 sprintf(net_dev->name, "ec%u", master->index); |
366 sprintf(net_dev->name, "ec%u", master->index); |
376 *ecdev = master->device; // offer accepted |
367 *ecdev = &master->main_device; // offer accepted |
377 return 0; // no error |
368 return 0; // no error |
378 } |
369 } |
379 |
|
380 up(&master->device_sem); |
|
381 } |
370 } |
382 |
371 |
383 *ecdev = NULL; // offer declined |
372 *ecdev = NULL; // offer declined |
384 return 0; // no error |
373 return 0; // no error |
385 |
|
386 out_free: |
|
387 kfree(master->device); |
|
388 master->device = NULL; |
|
389 out_up: |
|
390 up(&master->device_sem); |
|
391 out_return: |
|
392 return 1; |
|
393 } |
374 } |
394 |
375 |
395 /*****************************************************************************/ |
376 /*****************************************************************************/ |
396 |
377 |
397 /** |
378 /** |
411 ec_device_id_print(master->main_device_id, str); |
392 ec_device_id_print(master->main_device_id, str); |
412 |
393 |
413 EC_INFO("Master %u releasing main device %s.\n", master->index, str); |
394 EC_INFO("Master %u releasing main device %s.\n", master->index, str); |
414 |
395 |
415 down(&master->device_sem); |
396 down(&master->device_sem); |
416 master->device = NULL; |
397 ec_device_detach(device); |
417 up(&master->device_sem); |
398 up(&master->device_sem); |
418 |
|
419 ec_device_clear(device); |
|
420 kfree(device); |
|
421 } |
399 } |
422 |
400 |
423 /*****************************************************************************/ |
401 /*****************************************************************************/ |
424 |
402 |
425 /** |
403 /** |
501 if (down_interruptible(&master->device_sem)) { |
479 if (down_interruptible(&master->device_sem)) { |
502 EC_ERR("Interrupted while waiting for device!\n"); |
480 EC_ERR("Interrupted while waiting for device!\n"); |
503 goto out_release; |
481 goto out_release; |
504 } |
482 } |
505 |
483 |
506 if (!master->device) { |
484 if (master->mode != EC_MASTER_MODE_IDLE) { |
507 up(&master->device_sem); |
485 up(&master->device_sem); |
508 EC_ERR("Master %i has no assigned device!\n", master_index); |
486 EC_ERR("Master %i still waiting for devices!\n", master_index); |
509 goto out_release; |
487 goto out_release; |
510 } |
488 } |
511 |
489 |
512 if (!try_module_get(master->device->module)) { |
490 if (!try_module_get(master->main_device.module)) { |
513 up(&master->device_sem); |
491 up(&master->device_sem); |
514 EC_ERR("Device module is unloading!\n"); |
492 EC_ERR("Device module is unloading!\n"); |
515 goto out_release; |
493 goto out_release; |
516 } |
494 } |
517 |
495 |
518 up(&master->device_sem); |
496 up(&master->device_sem); |
519 |
497 |
520 if (!master->device->link_state) { |
498 if (!master->main_device.link_state) { |
521 EC_ERR("Link is DOWN.\n"); |
499 EC_ERR("Link is DOWN.\n"); |
522 goto out_module_put; |
500 goto out_module_put; |
523 } |
501 } |
524 |
502 |
525 if (ec_master_enter_operation_mode(master)) { |
503 if (ec_master_enter_operation_mode(master)) { |