diff options
Diffstat (limited to 'drivers/ieee1394/raw1394.c')
-rw-r--r-- | drivers/ieee1394/raw1394.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index ad2108f27a04..a77a832828c8 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c | |||
@@ -636,27 +636,32 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) | |||
636 | 636 | ||
637 | case RAW1394_REQ_SET_CARD: | 637 | case RAW1394_REQ_SET_CARD: |
638 | spin_lock_irqsave(&host_info_lock, flags); | 638 | spin_lock_irqsave(&host_info_lock, flags); |
639 | if (req->req.misc < host_count) { | 639 | if (req->req.misc >= host_count) { |
640 | list_for_each_entry(hi, &host_info_list, list) { | ||
641 | if (!req->req.misc--) | ||
642 | break; | ||
643 | } | ||
644 | get_device(&hi->host->device); // XXX Need to handle failure case | ||
645 | list_add_tail(&fi->list, &hi->file_info_list); | ||
646 | fi->host = hi->host; | ||
647 | fi->state = connected; | ||
648 | |||
649 | req->req.error = RAW1394_ERROR_NONE; | ||
650 | req->req.generation = get_hpsb_generation(fi->host); | ||
651 | req->req.misc = (fi->host->node_id << 16) | ||
652 | | fi->host->node_count; | ||
653 | if (fi->protocol_version > 3) { | ||
654 | req->req.misc |= | ||
655 | NODEID_TO_NODE(fi->host->irm_id) << 8; | ||
656 | } | ||
657 | } else { | ||
658 | req->req.error = RAW1394_ERROR_INVALID_ARG; | 640 | req->req.error = RAW1394_ERROR_INVALID_ARG; |
641 | goto out_set_card; | ||
659 | } | 642 | } |
643 | list_for_each_entry(hi, &host_info_list, list) | ||
644 | if (!req->req.misc--) | ||
645 | break; | ||
646 | get_device(&hi->host->device); /* FIXME handle failure case */ | ||
647 | list_add_tail(&fi->list, &hi->file_info_list); | ||
648 | |||
649 | /* prevent unloading of the host's low-level driver */ | ||
650 | if (!try_module_get(hi->host->driver->owner)) { | ||
651 | req->req.error = RAW1394_ERROR_ABORTED; | ||
652 | goto out_set_card; | ||
653 | } | ||
654 | WARN_ON(fi->host); | ||
655 | fi->host = hi->host; | ||
656 | fi->state = connected; | ||
657 | |||
658 | req->req.error = RAW1394_ERROR_NONE; | ||
659 | req->req.generation = get_hpsb_generation(fi->host); | ||
660 | req->req.misc = (fi->host->node_id << 16) | ||
661 | | fi->host->node_count; | ||
662 | if (fi->protocol_version > 3) | ||
663 | req->req.misc |= NODEID_TO_NODE(fi->host->irm_id) << 8; | ||
664 | out_set_card: | ||
660 | spin_unlock_irqrestore(&host_info_lock, flags); | 665 | spin_unlock_irqrestore(&host_info_lock, flags); |
661 | 666 | ||
662 | req->req.length = 0; | 667 | req->req.length = 0; |
@@ -2955,6 +2960,11 @@ static int raw1394_release(struct inode *inode, struct file *file) | |||
2955 | put_device(&fi->host->device); | 2960 | put_device(&fi->host->device); |
2956 | } | 2961 | } |
2957 | 2962 | ||
2963 | spin_lock_irqsave(&host_info_lock, flags); | ||
2964 | if (fi->host) | ||
2965 | module_put(fi->host->driver->owner); | ||
2966 | spin_unlock_irqrestore(&host_info_lock, flags); | ||
2967 | |||
2958 | kfree(fi); | 2968 | kfree(fi); |
2959 | 2969 | ||
2960 | return 0; | 2970 | return 0; |