Skip to content

Commit

Permalink
firewire: introduce fw_driver.probe and .remove methods
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Clemens Ladisch <[email protected]> (for sound/firewire/)
Cc: Peter Hurley <[email protected]> (for drivers/staging/fwserial/)
  • Loading branch information
Stefan Richter committed Jun 9, 2013
1 parent 317ddd2 commit 94a8715
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 170 deletions.
45 changes: 36 additions & 9 deletions drivers/firewire/core-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down
50 changes: 24 additions & 26 deletions drivers/firewire/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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[] = {
Expand All @@ -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,
};

Expand Down
17 changes: 7 additions & 10 deletions drivers/firewire/sbp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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,
};

Expand Down
19 changes: 9 additions & 10 deletions drivers/media/firewire/firedtv-fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ static const char * const model_names[] = {
/* Adjust the template string if models with longer names appear. */
#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")

static int node_probe(struct device *dev)
static int node_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
{
struct firedtv *fdtv;
char name[MAX_MODEL_NAME_LEN];
Expand All @@ -258,8 +258,8 @@ static int node_probe(struct device *dev)
if (!fdtv)
return -ENOMEM;

dev_set_drvdata(dev, fdtv);
fdtv->device = dev;
dev_set_drvdata(&unit->device, fdtv);
fdtv->device = &unit->device;
fdtv->isochannel = -1;
fdtv->voltage = 0xff;
fdtv->tone = 0xff;
Expand All @@ -269,15 +269,15 @@ static int node_probe(struct device *dev)
mutex_init(&fdtv->demux_mutex);
INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);

name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
name_len = fw_csr_string(unit->directory, CSR_MODEL,
name, sizeof(name));
for (i = ARRAY_SIZE(model_names); --i; )
if (strlen(model_names[i]) <= name_len &&
strncmp(name, model_names[i], name_len) == 0)
break;
fdtv->type = i;

err = fdtv_register_rc(fdtv, dev);
err = fdtv_register_rc(fdtv, &unit->device);
if (err)
goto fail_free;

Expand Down Expand Up @@ -307,9 +307,9 @@ static int node_probe(struct device *dev)
return err;
}

static int node_remove(struct device *dev)
static void node_remove(struct fw_unit *unit)
{
struct firedtv *fdtv = dev_get_drvdata(dev);
struct firedtv *fdtv = dev_get_drvdata(&unit->device);

fdtv_dvb_unregister(fdtv);

Expand All @@ -320,7 +320,6 @@ static int node_remove(struct device *dev)
fdtv_unregister_rc(fdtv);

kfree(fdtv);
return 0;
}

static void node_update(struct fw_unit *unit)
Expand Down Expand Up @@ -391,10 +390,10 @@ static struct fw_driver fdtv_driver = {
.owner = THIS_MODULE,
.name = "firedtv",
.bus = &fw_bus_type,
.probe = node_probe,
.remove = node_remove,
},
.probe = node_probe,
.update = node_update,
.remove = node_remove,
.id_table = fdtv_id_table,
};

Expand Down
14 changes: 6 additions & 8 deletions drivers/staging/fwserial/fwserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -2438,9 +2438,9 @@ static int fwserial_create(struct fw_unit *unit)
* last peer for a given fw_card triggering the destruction of the same
* fw_serial for the same fw_card.
*/
static int fwserial_probe(struct device *dev)
static int fwserial_probe(struct fw_unit *unit,
const struct ieee1394_device_id *id)
{
struct fw_unit *unit = fw_unit(dev);
struct fw_serial *serial;
int err;

Expand All @@ -2462,9 +2462,9 @@ static int fwserial_probe(struct device *dev)
* specific fw_card). If this is the last peer being removed, then trigger
* the destruction of the underlying TTYs.
*/
static int fwserial_remove(struct device *dev)
static void fwserial_remove(struct fw_unit *unit)
{
struct fwtty_peer *peer = dev_get_drvdata(dev);
struct fwtty_peer *peer = dev_get_drvdata(&unit->device);
struct fw_serial *serial = peer->serial;
int i;

Expand All @@ -2484,8 +2484,6 @@ static int fwserial_remove(struct device *dev)
kref_put(&serial->kref, fwserial_destroy);
}
mutex_unlock(&fwserial_list_mutex);

return 0;
}

/**
Expand Down Expand Up @@ -2530,10 +2528,10 @@ static struct fw_driver fwserial_driver = {
.owner = THIS_MODULE,
.name = KBUILD_MODNAME,
.bus = &fw_bus_type,
.probe = fwserial_probe,
.remove = fwserial_remove,
},
.probe = fwserial_probe,
.update = fwserial_update,
.remove = fwserial_remove,
.id_table = fwserial_id_table,
};

Expand Down
2 changes: 2 additions & 0 deletions include/linux/firewire.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,10 @@ struct ieee1394_device_id;

struct fw_driver {
struct device_driver driver;
int (*probe)(struct fw_unit *unit, const struct ieee1394_device_id *id);
/* Called when the parent device sits through a bus reset. */
void (*update)(struct fw_unit *unit);
void (*remove)(struct fw_unit *unit);
const struct ieee1394_device_id *id_table;
};

Expand Down
Loading

0 comments on commit 94a8715

Please sign in to comment.