Commit bb93109e authored by Linus Torvalds's avatar Linus Torvalds

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
parents 23e3a1d9 bcabcfd2
...@@ -165,25 +165,44 @@ static bool match_ids(const struct ieee1394_device_id *id_table, int *id) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 = { ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 = { ...@@ -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[] = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ static int node_probe(struct device *dev) ...@@ -307,9 +307,9 @@ static int node_probe(struct device *dev)
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) ...@@ -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 = { ...@@ -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 @@ static int fwserial_create(struct fw_unit *unit) ...@@ -2446,9 +2446,9 @@ static int fwserial_create(struct fw_unit *unit)
* 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) ...@@ -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) ...@@ -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 = { ...@@ -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; ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,34 +686,32 @@ static int isight_probe(struct device *unit_dev) ...@@ -686,34 +686,32 @@ static int isight_probe(struct device *unit_dev)
return err; return err;
} }
static int isight_remove(struct device *dev) static void isight_bus_reset(struct fw_unit *unit)
{ {
struct isight *isight = dev_get_drvdata(dev); struct isight *isight = dev_get_drvdata(&unit->device);
if (fw_iso_resources_update(&isight->resources) < 0) {
isight_pcm_abort(isight); isight_pcm_abort(isight);
snd_card_disconnect(isight->card);
mutex_lock(&isight->mutex); mutex_lock(&isight->mutex);
isight_stop_streaming(isight); isight_stop_streaming(isight);
mutex_unlock(&isight->mutex); 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_remove(struct fw_unit *unit)
{ {
struct isight *isight = dev_get_drvdata(&unit->device); struct isight *isight = dev_get_drvdata(&unit->device);
if (fw_iso_resources_update(&isight->resources) < 0) {
isight_pcm_abort(isight); isight_pcm_abort(isight);
snd_card_disconnect(isight->card);
mutex_lock(&isight->mutex); mutex_lock(&isight->mutex);
isight_stop_streaming(isight); isight_stop_streaming(isight);
mutex_unlock(&isight->mutex); 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[] = {
...@@ -732,10 +730,10 @@ static struct fw_driver isight_driver = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,9 +452,20 @@ static int scs_probe(struct device *unit_dev) ...@@ -453,9 +452,20 @@ static int scs_probe(struct device *unit_dev)
return err; return err;
} }
static int scs_remove(struct device *dev) static void scs_update(struct fw_unit *unit)
{ {
struct scs *scs = dev_get_drvdata(dev); struct scs *scs = dev_get_drvdata(&unit->device);
__be64 data;
data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
scs->hss_handler.offset);
snd_fw_transaction(scs->unit, TCODE_WRITE_BLOCK_REQUEST,
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); snd_card_disconnect(scs->card);
...@@ -467,19 +477,6 @@ static int scs_remove(struct device *dev) ...@@ -467,19 +477,6 @@ static int scs_remove(struct device *dev)
tasklet_kill(&scs->tasklet); tasklet_kill(&scs->tasklet);
snd_card_free_when_closed(scs->card); snd_card_free_when_closed(scs->card);
return 0;
}
static void scs_update(struct fw_unit *unit)
{
struct scs *scs = dev_get_drvdata(&unit->device);
__be64 data;
data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
scs->hss_handler.offset);
snd_fw_transaction(scs->unit, TCODE_WRITE_BLOCK_REQUEST,
HSS1394_ADDRESS, &data, 8);
} }
static const struct ieee1394_device_id scs_id_table[] = { static const struct ieee1394_device_id scs_id_table[] = {
...@@ -508,10 +505,10 @@ static struct fw_driver scs_driver = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,39 +730,57 @@ static int fwspk_probe(struct device *unit_dev) ...@@ -770,39 +730,57 @@ static int fwspk_probe(struct device *unit_dev)
return err; return err;
} }
static int fwspk_remove(struct device *dev) static void fwspk_bus_reset(struct fw_unit *unit)
{ {
struct fwspk *fwspk = dev_get_drvdata(dev); struct fwspk *fwspk = dev_get_drvdata(&unit->device);
amdtp_out_stream_pcm_abort(&fwspk->stream); fcp_bus_reset(fwspk->unit);
snd_card_disconnect(fwspk->card);
if (cmp_connection_update(&fwspk->connection) < 0) {
amdtp_out_stream_pcm_abort(&fwspk->stream);
mutex_lock(&fwspk->mutex); mutex_lock(&fwspk->mutex);
fwspk_stop_stream(fwspk); fwspk_stop_stream(fwspk);
mutex_unlock(&fwspk->mutex); mutex_unlock(&fwspk->mutex);
return;
}
snd_card_free_when_closed(fwspk->card); amdtp_out_stream_update(&fwspk->stream);
return 0;
} }
static void fwspk_bus_reset(struct fw_unit *unit) static void fwspk_remove(struct fw_unit *unit)
{ {
struct fwspk *fwspk = dev_get_drvdata(&unit->device); struct fwspk *fwspk = dev_get_drvdata(&unit->device);
fcp_bus_reset(fwspk->unit);
if (cmp_connection_update(&fwspk->connection) < 0) {
amdtp_out_stream_pcm_abort(&fwspk->stream); amdtp_out_stream_pcm_abort(&fwspk->stream);
snd_card_disconnect(fwspk->card);
mutex_lock(&fwspk->mutex); mutex_lock(&fwspk->mutex);
fwspk_stop_stream(fwspk); fwspk_stop_stream(fwspk);
mutex_unlock(&fwspk->mutex); mutex_unlock(&fwspk->mutex);
return;
}
amdtp_out_stream_update(&fwspk->stream); 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[] = { ...@@ -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[] = { ...@@ -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 = { ...@@ -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,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment