From e9603978b685461d7b6a031edfd223458c8d2305 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 3 Feb 2007 16:48:51 +0100 Subject: [PATCH] --- yaml --- r: 47320 b: refs/heads/master c: 0fe4c6fcacb28bda75b31f63d3629f640a6b9bf9 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/ieee1394/raw1394.c | 48 +++++++++++++++++++------------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/[refs] b/[refs] index 8eedbe3d25c7..98d69dc18f7a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 12ba145c9406da72c8288245f352de7f37188f1f +refs/heads/master: 0fe4c6fcacb28bda75b31f63d3629f640a6b9bf9 diff --git a/trunk/drivers/ieee1394/raw1394.c b/trunk/drivers/ieee1394/raw1394.c index ad2108f27a04..a77a832828c8 100644 --- a/trunk/drivers/ieee1394/raw1394.c +++ b/trunk/drivers/ieee1394/raw1394.c @@ -636,27 +636,32 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) case RAW1394_REQ_SET_CARD: spin_lock_irqsave(&host_info_lock, flags); - if (req->req.misc < host_count) { - list_for_each_entry(hi, &host_info_list, list) { - if (!req->req.misc--) - break; - } - get_device(&hi->host->device); // XXX Need to handle failure case - list_add_tail(&fi->list, &hi->file_info_list); - fi->host = hi->host; - fi->state = connected; - - req->req.error = RAW1394_ERROR_NONE; - req->req.generation = get_hpsb_generation(fi->host); - req->req.misc = (fi->host->node_id << 16) - | fi->host->node_count; - if (fi->protocol_version > 3) { - req->req.misc |= - NODEID_TO_NODE(fi->host->irm_id) << 8; - } - } else { + if (req->req.misc >= host_count) { req->req.error = RAW1394_ERROR_INVALID_ARG; + goto out_set_card; } + list_for_each_entry(hi, &host_info_list, list) + if (!req->req.misc--) + break; + get_device(&hi->host->device); /* FIXME handle failure case */ + list_add_tail(&fi->list, &hi->file_info_list); + + /* prevent unloading of the host's low-level driver */ + if (!try_module_get(hi->host->driver->owner)) { + req->req.error = RAW1394_ERROR_ABORTED; + goto out_set_card; + } + WARN_ON(fi->host); + fi->host = hi->host; + fi->state = connected; + + req->req.error = RAW1394_ERROR_NONE; + req->req.generation = get_hpsb_generation(fi->host); + req->req.misc = (fi->host->node_id << 16) + | fi->host->node_count; + if (fi->protocol_version > 3) + req->req.misc |= NODEID_TO_NODE(fi->host->irm_id) << 8; +out_set_card: spin_unlock_irqrestore(&host_info_lock, flags); req->req.length = 0; @@ -2955,6 +2960,11 @@ static int raw1394_release(struct inode *inode, struct file *file) put_device(&fi->host->device); } + spin_lock_irqsave(&host_info_lock, flags); + if (fi->host) + module_put(fi->host->driver->owner); + spin_unlock_irqrestore(&host_info_lock, flags); + kfree(fi); return 0;