IEEE 1394 (FireWire) subsystem changes post v3.10:
Make struct ieee1394_device_id.driver_data actually avaliable to 1394 protocol drivers. This is especially useful to 1394 audio drivers for model-specific parameters and methods. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (GNU/Linux) iQIcBAABAgAGBQJR2Sb3AAoJEHnzb7JUXXnQqqcQAOY/01VNTih1BuTnuDDtKQdq DQ9aO7zBc/aFY0baImrmbaZ7KUlwKKrFNaQMI63gj/ESyGIK6njRgPIS2I0eQSL1 Wb+4FXsOqtyXlRnL2eCHOl0o5ZrVyZD/ZDpBh+AxTl7nZYM5hX1ARDSeRX4SD/og KWTrSV6GtTijJaTGLQ+d5AY5QndT754LvgRcqVStsL2/pt3aeCpuIEAo6osXrD7u IsaJS7FSmrNnOKQFA7JFJVvBLyF+xxjNW/XQAnZ5NGbLOmB9jnyCKjOk9YE97/Sb qAacO3FEo7GUT5qksV/awuaGZpIfWEVCb9oD3heui1F0XSxrPUq8RXTJHa/g/BK7 q2feV1lv9ZAJWjLTePlB4TNgym+oVr1OqhsspHnM7mHhALKZwbDmDusxkFK8EH7P v7WNBwyik03qY3A6mgbTxUKcmiem9maCcyE1acPnHFqch0QafILwK6qPQb1oMG5Y BDdRNCXxNLGMasRsMDvKabHhs1u+KZ4/qUwooKdLbRL/WJuRHVU+UveTQ2f+90HY 0UEgplUfphrX9QyWqm7NHxwxVW83NnihcgkDgdVw77ARblJDYB5nLyqS1eIYF6xa 59h0b3DDM7SaaGVS9niOuwz9p8ZdXNY2VKn+byA5zyy/xNB06KVXlDydEXV2G7mv HZqMzX54d6zdf51v/UgT =8MqX -----END PGP SIGNATURE----- Merge tag 'firewire-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394 Pull firewire updates from Stefan Richter: "Make struct ieee1394_device_id.driver_data actually avaliable to 1394 protocol drivers. This is especially useful to 1394 audio drivers for model-specific parameters and methods" * tag 'firewire-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394: firewire: remove support of fw_driver.driver.probe and .remove methods firewire: introduce fw_driver.probe and .remove methods
This commit is contained in:
commit
bb93109e15
9 changed files with 163 additions and 173 deletions
|
@ -165,25 +165,44 @@ static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
|
||||||
return (match & id_table->match_flags) == id_table->match_flags;
|
return (match & id_table->match_flags) == id_table->match_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_fw_unit(struct device *dev);
|
static const struct ieee1394_device_id *unit_match(struct device *dev,
|
||||||
|
struct device_driver *drv)
|
||||||
static int fw_unit_match(struct device *dev, struct device_driver *drv)
|
|
||||||
{
|
{
|
||||||
const struct ieee1394_device_id *id_table =
|
const struct ieee1394_device_id *id_table =
|
||||||
container_of(drv, struct fw_driver, driver)->id_table;
|
container_of(drv, struct fw_driver, driver)->id_table;
|
||||||
int id[] = {0, 0, 0, 0};
|
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);
|
get_modalias_ids(fw_unit(dev), id);
|
||||||
|
|
||||||
for (; id_table->match_flags != 0; id_table++)
|
for (; id_table->match_flags != 0; id_table++)
|
||||||
if (match_ids(id_table, id))
|
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);
|
||||||
|
|
||||||
|
return driver->probe(fw_unit(dev), unit_match(dev, dev->driver));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fw_unit_remove(struct device *dev)
|
||||||
|
{
|
||||||
|
struct fw_driver *driver =
|
||||||
|
container_of(dev->driver, struct fw_driver, driver);
|
||||||
|
|
||||||
|
return driver->remove(fw_unit(dev)), 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
|
static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
|
||||||
|
@ -213,6 +232,8 @@ static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
struct bus_type fw_bus_type = {
|
struct bus_type fw_bus_type = {
|
||||||
.name = "firewire",
|
.name = "firewire",
|
||||||
.match = fw_unit_match,
|
.match = fw_unit_match,
|
||||||
|
.probe = fw_unit_probe,
|
||||||
|
.remove = fw_unit_remove,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL(fw_bus_type);
|
EXPORT_SYMBOL(fw_bus_type);
|
||||||
|
|
||||||
|
|
|
@ -1440,9 +1440,9 @@ static int fwnet_add_peer(struct fwnet_device *dev,
|
||||||
return 0;
|
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_device *device = fw_parent_device(unit);
|
||||||
struct fw_card *card = device->card;
|
struct fw_card *card = device->card;
|
||||||
struct net_device *net;
|
struct net_device *net;
|
||||||
|
@ -1526,6 +1526,24 @@ static int fwnet_probe(struct device *_dev)
|
||||||
return ret;
|
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)
|
static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
|
||||||
{
|
{
|
||||||
struct fwnet_partial_datagram *pd, *pd_next;
|
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);
|
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 fwnet_device *dev = peer->dev;
|
||||||
struct net_device *net;
|
struct net_device *net;
|
||||||
int i;
|
int i;
|
||||||
|
@ -1569,26 +1587,6 @@ static int fwnet_remove(struct device *_dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&fwnet_device_mutex);
|
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[] = {
|
static const struct ieee1394_device_id fwnet_id_table[] = {
|
||||||
|
@ -1614,10 +1612,10 @@ static struct fw_driver fwnet_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = KBUILD_MODNAME,
|
.name = KBUILD_MODNAME,
|
||||||
.bus = &fw_bus_type,
|
.bus = &fw_bus_type,
|
||||||
.probe = fwnet_probe,
|
|
||||||
.remove = fwnet_remove,
|
|
||||||
},
|
},
|
||||||
|
.probe = fwnet_probe,
|
||||||
.update = fwnet_update,
|
.update = fwnet_update,
|
||||||
|
.remove = fwnet_remove,
|
||||||
.id_table = fwnet_id_table,
|
.id_table = fwnet_id_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1128,11 +1128,10 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct scsi_host_template scsi_driver_template;
|
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 fw_device *device = fw_parent_device(unit);
|
||||||
struct sbp2_target *tgt;
|
struct sbp2_target *tgt;
|
||||||
struct sbp2_logical_unit *lu;
|
struct sbp2_logical_unit *lu;
|
||||||
|
@ -1196,7 +1195,7 @@ static int sbp2_probe(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_remove:
|
fail_remove:
|
||||||
sbp2_remove(dev);
|
sbp2_remove(unit);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
fail_shost_put:
|
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 fw_device *device = fw_parent_device(unit);
|
||||||
struct sbp2_target *tgt = dev_get_drvdata(&unit->device);
|
struct sbp2_target *tgt = dev_get_drvdata(&unit->device);
|
||||||
struct sbp2_logical_unit *lu, *next;
|
struct sbp2_logical_unit *lu, *next;
|
||||||
|
@ -1261,10 +1259,9 @@ static int sbp2_remove(struct device *dev)
|
||||||
kfree(lu);
|
kfree(lu);
|
||||||
}
|
}
|
||||||
scsi_remove_host(shost);
|
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);
|
scsi_host_put(shost);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
|
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
|
||||||
|
@ -1285,10 +1282,10 @@ static struct fw_driver sbp2_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = KBUILD_MODNAME,
|
.name = KBUILD_MODNAME,
|
||||||
.bus = &fw_bus_type,
|
.bus = &fw_bus_type,
|
||||||
.probe = sbp2_probe,
|
|
||||||
.remove = sbp2_remove,
|
|
||||||
},
|
},
|
||||||
|
.probe = sbp2_probe,
|
||||||
.update = sbp2_update,
|
.update = sbp2_update,
|
||||||
|
.remove = sbp2_remove,
|
||||||
.id_table = sbp2_id_table,
|
.id_table = sbp2_id_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -248,7 +248,7 @@ static const char * const model_names[] = {
|
||||||
/* Adjust the template string if models with longer names appear. */
|
/* Adjust the template string if models with longer names appear. */
|
||||||
#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")
|
#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;
|
struct firedtv *fdtv;
|
||||||
char name[MAX_MODEL_NAME_LEN];
|
char name[MAX_MODEL_NAME_LEN];
|
||||||
|
@ -258,8 +258,8 @@ static int node_probe(struct device *dev)
|
||||||
if (!fdtv)
|
if (!fdtv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
dev_set_drvdata(dev, fdtv);
|
dev_set_drvdata(&unit->device, fdtv);
|
||||||
fdtv->device = dev;
|
fdtv->device = &unit->device;
|
||||||
fdtv->isochannel = -1;
|
fdtv->isochannel = -1;
|
||||||
fdtv->voltage = 0xff;
|
fdtv->voltage = 0xff;
|
||||||
fdtv->tone = 0xff;
|
fdtv->tone = 0xff;
|
||||||
|
@ -269,7 +269,7 @@ static int node_probe(struct device *dev)
|
||||||
mutex_init(&fdtv->demux_mutex);
|
mutex_init(&fdtv->demux_mutex);
|
||||||
INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
|
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));
|
name, sizeof(name));
|
||||||
for (i = ARRAY_SIZE(model_names); --i; )
|
for (i = ARRAY_SIZE(model_names); --i; )
|
||||||
if (strlen(model_names[i]) <= name_len &&
|
if (strlen(model_names[i]) <= name_len &&
|
||||||
|
@ -277,7 +277,7 @@ static int node_probe(struct device *dev)
|
||||||
break;
|
break;
|
||||||
fdtv->type = i;
|
fdtv->type = i;
|
||||||
|
|
||||||
err = fdtv_register_rc(fdtv, dev);
|
err = fdtv_register_rc(fdtv, &unit->device);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail_free;
|
goto fail_free;
|
||||||
|
|
||||||
|
@ -307,9 +307,9 @@ fail_free:
|
||||||
return err;
|
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);
|
fdtv_dvb_unregister(fdtv);
|
||||||
|
|
||||||
|
@ -320,7 +320,6 @@ static int node_remove(struct device *dev)
|
||||||
fdtv_unregister_rc(fdtv);
|
fdtv_unregister_rc(fdtv);
|
||||||
|
|
||||||
kfree(fdtv);
|
kfree(fdtv);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void node_update(struct fw_unit *unit)
|
static void node_update(struct fw_unit *unit)
|
||||||
|
@ -391,10 +390,10 @@ static struct fw_driver fdtv_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "firedtv",
|
.name = "firedtv",
|
||||||
.bus = &fw_bus_type,
|
.bus = &fw_bus_type,
|
||||||
.probe = node_probe,
|
|
||||||
.remove = node_remove,
|
|
||||||
},
|
},
|
||||||
|
.probe = node_probe,
|
||||||
.update = node_update,
|
.update = node_update,
|
||||||
|
.remove = node_remove,
|
||||||
.id_table = fdtv_id_table,
|
.id_table = fdtv_id_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2446,9 +2446,9 @@ free_ports:
|
||||||
* last peer for a given fw_card triggering the destruction of the same
|
* last peer for a given fw_card triggering the destruction of the same
|
||||||
* fw_serial for the same fw_card.
|
* 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;
|
struct fw_serial *serial;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -2470,9 +2470,9 @@ static int fwserial_probe(struct device *dev)
|
||||||
* specific fw_card). If this is the last peer being removed, then trigger
|
* specific fw_card). If this is the last peer being removed, then trigger
|
||||||
* the destruction of the underlying TTYs.
|
* 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;
|
struct fw_serial *serial = peer->serial;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -2492,8 +2492,6 @@ static int fwserial_remove(struct device *dev)
|
||||||
kref_put(&serial->kref, fwserial_destroy);
|
kref_put(&serial->kref, fwserial_destroy);
|
||||||
}
|
}
|
||||||
mutex_unlock(&fwserial_list_mutex);
|
mutex_unlock(&fwserial_list_mutex);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2538,10 +2536,10 @@ static struct fw_driver fwserial_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = KBUILD_MODNAME,
|
.name = KBUILD_MODNAME,
|
||||||
.bus = &fw_bus_type,
|
.bus = &fw_bus_type,
|
||||||
.probe = fwserial_probe,
|
|
||||||
.remove = fwserial_remove,
|
|
||||||
},
|
},
|
||||||
|
.probe = fwserial_probe,
|
||||||
.update = fwserial_update,
|
.update = fwserial_update,
|
||||||
|
.remove = fwserial_remove,
|
||||||
.id_table = fwserial_id_table,
|
.id_table = fwserial_id_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -251,8 +251,10 @@ struct ieee1394_device_id;
|
||||||
|
|
||||||
struct fw_driver {
|
struct fw_driver {
|
||||||
struct device_driver 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. */
|
/* Called when the parent device sits through a bus reset. */
|
||||||
void (*update)(struct fw_unit *unit);
|
void (*update)(struct fw_unit *unit);
|
||||||
|
void (*remove)(struct fw_unit *unit);
|
||||||
const struct ieee1394_device_id *id_table;
|
const struct ieee1394_device_id *id_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -626,9 +626,9 @@ static u64 get_unit_base(struct fw_unit *unit)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isight_probe(struct device *unit_dev)
|
static int isight_probe(struct fw_unit *unit,
|
||||||
|
const struct ieee1394_device_id *id)
|
||||||
{
|
{
|
||||||
struct fw_unit *unit = fw_unit(unit_dev);
|
|
||||||
struct fw_device *fw_dev = fw_parent_device(unit);
|
struct fw_device *fw_dev = fw_parent_device(unit);
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct isight *isight;
|
struct isight *isight;
|
||||||
|
@ -637,7 +637,7 @@ static int isight_probe(struct device *unit_dev)
|
||||||
err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
|
err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_card_set_dev(card, unit_dev);
|
snd_card_set_dev(card, &unit->device);
|
||||||
|
|
||||||
isight = card->private_data;
|
isight = card->private_data;
|
||||||
isight->card = card;
|
isight->card = card;
|
||||||
|
@ -674,7 +674,7 @@ static int isight_probe(struct device *unit_dev)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
dev_set_drvdata(unit_dev, isight);
|
dev_set_drvdata(&unit->device, isight);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -686,23 +686,6 @@ error:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isight_remove(struct device *dev)
|
|
||||||
{
|
|
||||||
struct isight *isight = dev_get_drvdata(dev);
|
|
||||||
|
|
||||||
isight_pcm_abort(isight);
|
|
||||||
|
|
||||||
snd_card_disconnect(isight->card);
|
|
||||||
|
|
||||||
mutex_lock(&isight->mutex);
|
|
||||||
isight_stop_streaming(isight);
|
|
||||||
mutex_unlock(&isight->mutex);
|
|
||||||
|
|
||||||
snd_card_free_when_closed(isight->card);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void isight_bus_reset(struct fw_unit *unit)
|
static void isight_bus_reset(struct fw_unit *unit)
|
||||||
{
|
{
|
||||||
struct isight *isight = dev_get_drvdata(&unit->device);
|
struct isight *isight = dev_get_drvdata(&unit->device);
|
||||||
|
@ -716,6 +699,21 @@ static void isight_bus_reset(struct fw_unit *unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void isight_remove(struct fw_unit *unit)
|
||||||
|
{
|
||||||
|
struct isight *isight = dev_get_drvdata(&unit->device);
|
||||||
|
|
||||||
|
isight_pcm_abort(isight);
|
||||||
|
|
||||||
|
snd_card_disconnect(isight->card);
|
||||||
|
|
||||||
|
mutex_lock(&isight->mutex);
|
||||||
|
isight_stop_streaming(isight);
|
||||||
|
mutex_unlock(&isight->mutex);
|
||||||
|
|
||||||
|
snd_card_free_when_closed(isight->card);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ieee1394_device_id isight_id_table[] = {
|
static const struct ieee1394_device_id isight_id_table[] = {
|
||||||
{
|
{
|
||||||
.match_flags = IEEE1394_MATCH_SPECIFIER_ID |
|
.match_flags = IEEE1394_MATCH_SPECIFIER_ID |
|
||||||
|
@ -732,10 +730,10 @@ static struct fw_driver isight_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = KBUILD_MODNAME,
|
.name = KBUILD_MODNAME,
|
||||||
.bus = &fw_bus_type,
|
.bus = &fw_bus_type,
|
||||||
.probe = isight_probe,
|
|
||||||
.remove = isight_remove,
|
|
||||||
},
|
},
|
||||||
|
.probe = isight_probe,
|
||||||
.update = isight_bus_reset,
|
.update = isight_bus_reset,
|
||||||
|
.remove = isight_remove,
|
||||||
.id_table = isight_id_table,
|
.id_table = isight_id_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -384,9 +384,8 @@ static void scs_card_free(struct snd_card *card)
|
||||||
kfree(scs->buffer);
|
kfree(scs->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scs_probe(struct device *unit_dev)
|
static int scs_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
|
||||||
{
|
{
|
||||||
struct fw_unit *unit = fw_unit(unit_dev);
|
|
||||||
struct fw_device *fw_dev = fw_parent_device(unit);
|
struct fw_device *fw_dev = fw_parent_device(unit);
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct scs *scs;
|
struct scs *scs;
|
||||||
|
@ -395,7 +394,7 @@ static int scs_probe(struct device *unit_dev)
|
||||||
err = snd_card_create(-16, NULL, THIS_MODULE, sizeof(*scs), &card);
|
err = snd_card_create(-16, NULL, THIS_MODULE, sizeof(*scs), &card);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_card_set_dev(card, unit_dev);
|
snd_card_set_dev(card, &unit->device);
|
||||||
|
|
||||||
scs = card->private_data;
|
scs = card->private_data;
|
||||||
scs->card = card;
|
scs->card = card;
|
||||||
|
@ -442,7 +441,7 @@ static int scs_probe(struct device *unit_dev)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_card;
|
goto err_card;
|
||||||
|
|
||||||
dev_set_drvdata(unit_dev, scs);
|
dev_set_drvdata(&unit->device, scs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -453,24 +452,6 @@ err_card:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scs_remove(struct device *dev)
|
|
||||||
{
|
|
||||||
struct scs *scs = dev_get_drvdata(dev);
|
|
||||||
|
|
||||||
snd_card_disconnect(scs->card);
|
|
||||||
|
|
||||||
ACCESS_ONCE(scs->output) = NULL;
|
|
||||||
ACCESS_ONCE(scs->input) = NULL;
|
|
||||||
|
|
||||||
wait_event(scs->idle_wait, scs->output_idle);
|
|
||||||
|
|
||||||
tasklet_kill(&scs->tasklet);
|
|
||||||
|
|
||||||
snd_card_free_when_closed(scs->card);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scs_update(struct fw_unit *unit)
|
static void scs_update(struct fw_unit *unit)
|
||||||
{
|
{
|
||||||
struct scs *scs = dev_get_drvdata(&unit->device);
|
struct scs *scs = dev_get_drvdata(&unit->device);
|
||||||
|
@ -482,6 +463,22 @@ static void scs_update(struct fw_unit *unit)
|
||||||
HSS1394_ADDRESS, &data, 8);
|
HSS1394_ADDRESS, &data, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void scs_remove(struct fw_unit *unit)
|
||||||
|
{
|
||||||
|
struct scs *scs = dev_get_drvdata(&unit->device);
|
||||||
|
|
||||||
|
snd_card_disconnect(scs->card);
|
||||||
|
|
||||||
|
ACCESS_ONCE(scs->output) = NULL;
|
||||||
|
ACCESS_ONCE(scs->input) = NULL;
|
||||||
|
|
||||||
|
wait_event(scs->idle_wait, scs->output_idle);
|
||||||
|
|
||||||
|
tasklet_kill(&scs->tasklet);
|
||||||
|
|
||||||
|
snd_card_free_when_closed(scs->card);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ieee1394_device_id scs_id_table[] = {
|
static const struct ieee1394_device_id scs_id_table[] = {
|
||||||
{
|
{
|
||||||
.match_flags = IEEE1394_MATCH_VENDOR_ID |
|
.match_flags = IEEE1394_MATCH_VENDOR_ID |
|
||||||
|
@ -508,10 +505,10 @@ static struct fw_driver scs_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = KBUILD_MODNAME,
|
.name = KBUILD_MODNAME,
|
||||||
.bus = &fw_bus_type,
|
.bus = &fw_bus_type,
|
||||||
.probe = scs_probe,
|
|
||||||
.remove = scs_remove,
|
|
||||||
},
|
},
|
||||||
|
.probe = scs_probe,
|
||||||
.update = scs_update,
|
.update = scs_update,
|
||||||
|
.remove = scs_remove,
|
||||||
.id_table = scs_id_table,
|
.id_table = scs_id_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -663,45 +663,9 @@ static void fwspk_card_free(struct snd_card *card)
|
||||||
mutex_destroy(&fwspk->mutex);
|
mutex_destroy(&fwspk->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct device_info *fwspk_detect(struct fw_device *dev)
|
static int fwspk_probe(struct fw_unit *unit,
|
||||||
|
const struct ieee1394_device_id *id)
|
||||||
{
|
{
|
||||||
static const struct device_info griffin_firewave = {
|
|
||||||
.driver_name = "FireWave",
|
|
||||||
.short_name = "FireWave",
|
|
||||||
.long_name = "Griffin FireWave Surround",
|
|
||||||
.pcm_constraints = firewave_constraints,
|
|
||||||
.mixer_channels = 6,
|
|
||||||
.mute_fb_id = 0x01,
|
|
||||||
.volume_fb_id = 0x02,
|
|
||||||
};
|
|
||||||
static const struct device_info lacie_speakers = {
|
|
||||||
.driver_name = "FWSpeakers",
|
|
||||||
.short_name = "FireWire Speakers",
|
|
||||||
.long_name = "LaCie FireWire Speakers",
|
|
||||||
.pcm_constraints = lacie_speakers_constraints,
|
|
||||||
.mixer_channels = 1,
|
|
||||||
.mute_fb_id = 0x01,
|
|
||||||
.volume_fb_id = 0x01,
|
|
||||||
};
|
|
||||||
struct fw_csr_iterator i;
|
|
||||||
int key, value;
|
|
||||||
|
|
||||||
fw_csr_iterator_init(&i, dev->config_rom);
|
|
||||||
while (fw_csr_iterator_next(&i, &key, &value))
|
|
||||||
if (key == CSR_VENDOR)
|
|
||||||
switch (value) {
|
|
||||||
case VENDOR_GRIFFIN:
|
|
||||||
return &griffin_firewave;
|
|
||||||
case VENDOR_LACIE:
|
|
||||||
return &lacie_speakers;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fwspk_probe(struct device *unit_dev)
|
|
||||||
{
|
|
||||||
struct fw_unit *unit = fw_unit(unit_dev);
|
|
||||||
struct fw_device *fw_dev = fw_parent_device(unit);
|
struct fw_device *fw_dev = fw_parent_device(unit);
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct fwspk *fwspk;
|
struct fwspk *fwspk;
|
||||||
|
@ -711,17 +675,13 @@ static int fwspk_probe(struct device *unit_dev)
|
||||||
err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*fwspk), &card);
|
err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*fwspk), &card);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_card_set_dev(card, unit_dev);
|
snd_card_set_dev(card, &unit->device);
|
||||||
|
|
||||||
fwspk = card->private_data;
|
fwspk = card->private_data;
|
||||||
fwspk->card = card;
|
fwspk->card = card;
|
||||||
mutex_init(&fwspk->mutex);
|
mutex_init(&fwspk->mutex);
|
||||||
fwspk->unit = fw_unit_get(unit);
|
fwspk->unit = fw_unit_get(unit);
|
||||||
fwspk->device_info = fwspk_detect(fw_dev);
|
fwspk->device_info = (const struct device_info *)id->driver_data;
|
||||||
if (!fwspk->device_info) {
|
|
||||||
err = -ENODEV;
|
|
||||||
goto err_unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cmp_connection_init(&fwspk->connection, unit, 0);
|
err = cmp_connection_init(&fwspk->connection, unit, 0);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -756,7 +716,7 @@ static int fwspk_probe(struct device *unit_dev)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
dev_set_drvdata(unit_dev, fwspk);
|
dev_set_drvdata(&unit->device, fwspk);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -770,22 +730,6 @@ error:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fwspk_remove(struct device *dev)
|
|
||||||
{
|
|
||||||
struct fwspk *fwspk = dev_get_drvdata(dev);
|
|
||||||
|
|
||||||
amdtp_out_stream_pcm_abort(&fwspk->stream);
|
|
||||||
snd_card_disconnect(fwspk->card);
|
|
||||||
|
|
||||||
mutex_lock(&fwspk->mutex);
|
|
||||||
fwspk_stop_stream(fwspk);
|
|
||||||
mutex_unlock(&fwspk->mutex);
|
|
||||||
|
|
||||||
snd_card_free_when_closed(fwspk->card);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fwspk_bus_reset(struct fw_unit *unit)
|
static void fwspk_bus_reset(struct fw_unit *unit)
|
||||||
{
|
{
|
||||||
struct fwspk *fwspk = dev_get_drvdata(&unit->device);
|
struct fwspk *fwspk = dev_get_drvdata(&unit->device);
|
||||||
|
@ -803,6 +747,40 @@ static void fwspk_bus_reset(struct fw_unit *unit)
|
||||||
amdtp_out_stream_update(&fwspk->stream);
|
amdtp_out_stream_update(&fwspk->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fwspk_remove(struct fw_unit *unit)
|
||||||
|
{
|
||||||
|
struct fwspk *fwspk = dev_get_drvdata(&unit->device);
|
||||||
|
|
||||||
|
amdtp_out_stream_pcm_abort(&fwspk->stream);
|
||||||
|
snd_card_disconnect(fwspk->card);
|
||||||
|
|
||||||
|
mutex_lock(&fwspk->mutex);
|
||||||
|
fwspk_stop_stream(fwspk);
|
||||||
|
mutex_unlock(&fwspk->mutex);
|
||||||
|
|
||||||
|
snd_card_free_when_closed(fwspk->card);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct device_info griffin_firewave = {
|
||||||
|
.driver_name = "FireWave",
|
||||||
|
.short_name = "FireWave",
|
||||||
|
.long_name = "Griffin FireWave Surround",
|
||||||
|
.pcm_constraints = firewave_constraints,
|
||||||
|
.mixer_channels = 6,
|
||||||
|
.mute_fb_id = 0x01,
|
||||||
|
.volume_fb_id = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct device_info lacie_speakers = {
|
||||||
|
.driver_name = "FWSpeakers",
|
||||||
|
.short_name = "FireWire Speakers",
|
||||||
|
.long_name = "LaCie FireWire Speakers",
|
||||||
|
.pcm_constraints = lacie_speakers_constraints,
|
||||||
|
.mixer_channels = 1,
|
||||||
|
.mute_fb_id = 0x01,
|
||||||
|
.volume_fb_id = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct ieee1394_device_id fwspk_id_table[] = {
|
static const struct ieee1394_device_id fwspk_id_table[] = {
|
||||||
{
|
{
|
||||||
.match_flags = IEEE1394_MATCH_VENDOR_ID |
|
.match_flags = IEEE1394_MATCH_VENDOR_ID |
|
||||||
|
@ -813,6 +791,7 @@ static const struct ieee1394_device_id fwspk_id_table[] = {
|
||||||
.model_id = 0x00f970,
|
.model_id = 0x00f970,
|
||||||
.specifier_id = SPECIFIER_1394TA,
|
.specifier_id = SPECIFIER_1394TA,
|
||||||
.version = VERSION_AVC,
|
.version = VERSION_AVC,
|
||||||
|
.driver_data = (kernel_ulong_t)&griffin_firewave,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.match_flags = IEEE1394_MATCH_VENDOR_ID |
|
.match_flags = IEEE1394_MATCH_VENDOR_ID |
|
||||||
|
@ -823,6 +802,7 @@ static const struct ieee1394_device_id fwspk_id_table[] = {
|
||||||
.model_id = 0x00f970,
|
.model_id = 0x00f970,
|
||||||
.specifier_id = SPECIFIER_1394TA,
|
.specifier_id = SPECIFIER_1394TA,
|
||||||
.version = VERSION_AVC,
|
.version = VERSION_AVC,
|
||||||
|
.driver_data = (kernel_ulong_t)&lacie_speakers,
|
||||||
},
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
@ -833,10 +813,10 @@ static struct fw_driver fwspk_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = KBUILD_MODNAME,
|
.name = KBUILD_MODNAME,
|
||||||
.bus = &fw_bus_type,
|
.bus = &fw_bus_type,
|
||||||
.probe = fwspk_probe,
|
|
||||||
.remove = fwspk_remove,
|
|
||||||
},
|
},
|
||||||
|
.probe = fwspk_probe,
|
||||||
.update = fwspk_bus_reset,
|
.update = fwspk_bus_reset,
|
||||||
|
.remove = fwspk_remove,
|
||||||
.id_table = fwspk_id_table,
|
.id_table = fwspk_id_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue