summaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2013-06-09 18:15:00 +0200
committerStefan Richter <stefanr@s5r6.in-berlin.de>2013-06-09 18:15:00 +0200
commit94a87157cde95d38b9cdf1116e4f0fd93f6d25df (patch)
tree42cb11cbab50860a66d3e4191c43a85cf42bd77f /drivers/firewire
parent317ddd256b9c24b0d78fa8018f80f1e495481a10 (diff)
downloadop-kernel-dev-94a87157cde95d38b9cdf1116e4f0fd93f6d25df.zip
op-kernel-dev-94a87157cde95d38b9cdf1116e4f0fd93f6d25df.tar.gz
firewire: introduce fw_driver.probe and .remove methods
FireWire upper layer drivers are converted from generic struct driver.probe() and .remove() to bus-specific struct fw_driver.probe() and .remove(). The new .probe() adds a const struct ieee1394_device_id *id argument, indicating the entry in the driver's device identifiers table which matched the fw_unit to be probed. This new argument is used by the snd-firewire-speakers driver to look up device-specific parameters and methods. There is at least one other FireWire audio driver currently in development in which this will be useful too. The new .remove() drops the unused error return code. Although all in-tree drivers are being converted to the new methods, support for the old methods is left in place in this commit. This allows public developer trees to merge this commit and then move to the new fw_driver methods. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> Acked-by: Clemens Ladisch <clemens@ladisch.de> (for sound/firewire/) Cc: Peter Hurley <peter@hurleysoftware.com> (for drivers/staging/fwserial/)
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/core-device.c45
-rw-r--r--drivers/firewire/net.c50
-rw-r--r--drivers/firewire/sbp2.c17
3 files changed, 67 insertions, 45 deletions
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index 664a6ff..c152edd 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -165,25 +165,50 @@ static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
return (match & id_table->match_flags) == id_table->match_flags;
}
-static bool is_fw_unit(struct device *dev);
-
-static int fw_unit_match(struct device *dev, struct device_driver *drv)
+static const struct ieee1394_device_id *unit_match(struct device *dev,
+ struct device_driver *drv)
{
const struct ieee1394_device_id *id_table =
container_of(drv, struct fw_driver, driver)->id_table;
int id[] = {0, 0, 0, 0};
- /* We only allow binding to fw_units. */
- if (!is_fw_unit(dev))
- return 0;
-
get_modalias_ids(fw_unit(dev), id);
for (; id_table->match_flags != 0; id_table++)
if (match_ids(id_table, id))
- return 1;
+ return id_table;
- return 0;
+ return NULL;
+}
+
+static bool is_fw_unit(struct device *dev);
+
+static int fw_unit_match(struct device *dev, struct device_driver *drv)
+{
+ /* We only allow binding to fw_units. */
+ return is_fw_unit(dev) && unit_match(dev, drv) != NULL;
+}
+
+static int fw_unit_probe(struct device *dev)
+{
+ struct fw_driver *driver =
+ container_of(dev->driver, struct fw_driver, driver);
+
+ if (driver->probe)
+ return driver->probe(fw_unit(dev), unit_match(dev, dev->driver));
+ else
+ return driver->driver.probe(dev);
+}
+
+static int fw_unit_remove(struct device *dev)
+{
+ struct fw_driver *driver =
+ container_of(dev->driver, struct fw_driver, driver);
+
+ if (driver->remove)
+ return driver->remove(fw_unit(dev)), 0;
+ else
+ return driver->driver.remove(dev);
}
static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
@@ -213,6 +238,8 @@ static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
struct bus_type fw_bus_type = {
.name = "firewire",
.match = fw_unit_match,
+ .probe = fw_unit_probe,
+ .remove = fw_unit_remove,
};
EXPORT_SYMBOL(fw_bus_type);
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 815b0fc..6b89598 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1440,9 +1440,9 @@ static int fwnet_add_peer(struct fwnet_device *dev,
return 0;
}
-static int fwnet_probe(struct device *_dev)
+static int fwnet_probe(struct fw_unit *unit,
+ const struct ieee1394_device_id *id)
{
- struct fw_unit *unit = fw_unit(_dev);
struct fw_device *device = fw_parent_device(unit);
struct fw_card *card = device->card;
struct net_device *net;
@@ -1526,6 +1526,24 @@ static int fwnet_probe(struct device *_dev)
return ret;
}
+/*
+ * FIXME abort partially sent fragmented datagrams,
+ * discard partially received fragmented datagrams
+ */
+static void fwnet_update(struct fw_unit *unit)
+{
+ struct fw_device *device = fw_parent_device(unit);
+ struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
+ int generation;
+
+ generation = device->generation;
+
+ spin_lock_irq(&peer->dev->lock);
+ peer->node_id = device->node_id;
+ peer->generation = generation;
+ spin_unlock_irq(&peer->dev->lock);
+}
+
static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
{
struct fwnet_partial_datagram *pd, *pd_next;
@@ -1542,9 +1560,9 @@ static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
kfree(peer);
}
-static int fwnet_remove(struct device *_dev)
+static void fwnet_remove(struct fw_unit *unit)
{
- struct fwnet_peer *peer = dev_get_drvdata(_dev);
+ struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
struct fwnet_device *dev = peer->dev;
struct net_device *net;
int i;
@@ -1569,26 +1587,6 @@ static int fwnet_remove(struct device *_dev)
}
mutex_unlock(&fwnet_device_mutex);
-
- return 0;
-}
-
-/*
- * FIXME abort partially sent fragmented datagrams,
- * discard partially received fragmented datagrams
- */
-static void fwnet_update(struct fw_unit *unit)
-{
- struct fw_device *device = fw_parent_device(unit);
- struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
- int generation;
-
- generation = device->generation;
-
- spin_lock_irq(&peer->dev->lock);
- peer->node_id = device->node_id;
- peer->generation = generation;
- spin_unlock_irq(&peer->dev->lock);
}
static const struct ieee1394_device_id fwnet_id_table[] = {
@@ -1614,10 +1612,10 @@ static struct fw_driver fwnet_driver = {
.owner = THIS_MODULE,
.name = KBUILD_MODNAME,
.bus = &fw_bus_type,
- .probe = fwnet_probe,
- .remove = fwnet_remove,
},
+ .probe = fwnet_probe,
.update = fwnet_update,
+ .remove = fwnet_remove,
.id_table = fwnet_id_table,
};
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 47674b9..281029d 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1128,11 +1128,10 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
}
static struct scsi_host_template scsi_driver_template;
-static int sbp2_remove(struct device *dev);
+static void sbp2_remove(struct fw_unit *unit);
-static int sbp2_probe(struct device *dev)
+static int sbp2_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
{
- struct fw_unit *unit = fw_unit(dev);
struct fw_device *device = fw_parent_device(unit);
struct sbp2_target *tgt;
struct sbp2_logical_unit *lu;
@@ -1196,7 +1195,7 @@ static int sbp2_probe(struct device *dev)
return 0;
fail_remove:
- sbp2_remove(dev);
+ sbp2_remove(unit);
return -ENOMEM;
fail_shost_put:
@@ -1222,9 +1221,8 @@ static void sbp2_update(struct fw_unit *unit)
}
}
-static int sbp2_remove(struct device *dev)
+static void sbp2_remove(struct fw_unit *unit)
{
- struct fw_unit *unit = fw_unit(dev);
struct fw_device *device = fw_parent_device(unit);
struct sbp2_target *tgt = dev_get_drvdata(&unit->device);
struct sbp2_logical_unit *lu, *next;
@@ -1261,10 +1259,9 @@ static int sbp2_remove(struct device *dev)
kfree(lu);
}
scsi_remove_host(shost);
- dev_notice(dev, "released target %d:0:0\n", shost->host_no);
+ dev_notice(&unit->device, "released target %d:0:0\n", shost->host_no);
scsi_host_put(shost);
- return 0;
}
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
@@ -1285,10 +1282,10 @@ static struct fw_driver sbp2_driver = {
.owner = THIS_MODULE,
.name = KBUILD_MODNAME,
.bus = &fw_bus_type,
- .probe = sbp2_probe,
- .remove = sbp2_remove,
},
+ .probe = sbp2_probe,
.update = sbp2_update,
+ .remove = sbp2_remove,
.id_table = sbp2_id_table,
};
OpenPOWER on IntegriCloud