Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34699403 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull IEEE 1394 (FireWire) subsystem updates post v3.3 from Stefan Richter:

 - Some SBP-2 initiator fixes, side product from ongoing work on a target.

 - Reintroduction of an isochronous I/O feature of the older ieee1394 driver
   stack (flush buffer completions); it was evidently rarely used but not
   actually unused.  Matching libraw1394 code is already available.

 - Be sure to prefix all kernel log messages with device name or card name,
   and other logging related cleanups.

 - Misc other small cleanups, among them a small API change that affects
   sound/firewire/ too. Clemens Ladisch is aware of it.

* tag 'firewire-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394: (26 commits)
  firewire: allow explicit flushing of iso packet completions
  firewire: prevent dropping of completed iso packet header data
  firewire: ohci: factor out iso completion flushing code
  firewire: ohci: simplify iso header pointer arithmetic
  firewire: ohci: optimize control bit checks
  firewire: ohci: remove unused excess_bytes field
  firewire: ohci: copy_iso_headers(): make comment match the code
  firewire: cdev: fix IR multichannel event documentation
  firewire: ohci: fix too-early completion of IR multichannel buffers
  firewire: ohci: move runtime debug facility out of #ifdef
  firewire: tone down some diagnostic log messages
  firewire: sbp2: replace a GFP_ATOMIC allocation
  firewire: sbp2: Fix SCSI sense data mangling
  firewire: sbp2: Ignore SBP-2 targets on the local node
  firewire: sbp2: Take into account Unit_Unique_ID
  firewire: nosy: Use the macro DMA_BIT_MASK().
  firewire: core: convert AR-req handler lock from _irqsave to _bh
  firewire: core: fix race at address_handler unregistration
  firewire: core: remove obsolete comment
  firewire: core: prefix log messages with card name
  ...
parents 7fc86a79 d1bbd209
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -28,11 +28,6 @@ config FIREWIRE_OHCI
	  To compile this driver as a module, say M here:  The module will be
	  called firewire-ohci.

config FIREWIRE_OHCI_DEBUG
	bool
	depends on FIREWIRE_OHCI
	default y

config FIREWIRE_SBP2
	tristate "Storage devices (SBP-2 protocol)"
	depends on FIREWIRE && SCSI
+28 −6
Original line number Diff line number Diff line
@@ -37,6 +37,22 @@

#include "core.h"

#define define_fw_printk_level(func, kern_level)		\
void func(const struct fw_card *card, const char *fmt, ...)	\
{								\
	struct va_format vaf;					\
	va_list args;						\
								\
	va_start(args, fmt);					\
	vaf.fmt = fmt;						\
	vaf.va = &args;						\
	printk(kern_level KBUILD_MODNAME " %s: %pV",		\
	       dev_name(card->device), &vaf);			\
	va_end(args);						\
}
define_fw_printk_level(fw_err, KERN_ERR);
define_fw_printk_level(fw_notice, KERN_NOTICE);

int fw_compute_block_crc(__be32 *block)
{
	int length;
@@ -260,7 +276,7 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation)
		fw_iso_resource_manage(card, generation, 1ULL << 31,
				       &channel, &bandwidth, true);
		if (channel != 31) {
			fw_notify("failed to allocate broadcast channel\n");
			fw_notice(card, "failed to allocate broadcast channel\n");
			return;
		}
		card->broadcast_channel_allocated = true;
@@ -343,14 +359,14 @@ static void bm_work(struct work_struct *work)

		if (!card->irm_node->link_on) {
			new_root_id = local_id;
			fw_notify("%s, making local node (%02x) root.\n",
			fw_notice(card, "%s, making local node (%02x) root\n",
				  "IRM has link off", new_root_id);
			goto pick_me;
		}

		if (irm_is_1394_1995_only && !keep_this_irm) {
			new_root_id = local_id;
			fw_notify("%s, making local node (%02x) root.\n",
			fw_notice(card, "%s, making local node (%02x) root\n",
				  "IRM is not 1394a compliant", new_root_id);
			goto pick_me;
		}
@@ -405,7 +421,7 @@ static void bm_work(struct work_struct *work)
			 * root, and thus, IRM.
			 */
			new_root_id = local_id;
			fw_notify("%s, making local node (%02x) root.\n",
			fw_notice(card, "%s, making local node (%02x) root\n",
				  "BM lock failed", new_root_id);
			goto pick_me;
		}
@@ -478,8 +494,8 @@ static void bm_work(struct work_struct *work)
	spin_unlock_irq(&card->lock);

	if (do_reset) {
		fw_notify("phy config: card %d, new root=%x, gap_count=%d\n",
			  card->index, new_root_id, gap_count);
		fw_notice(card, "phy config: new root=%x, gap_count=%d\n",
			  new_root_id, gap_count);
		fw_send_phy_config(card, new_root_id, generation, gap_count);
		reset_bus(card, true);
		/* Will allocate broadcast channel after the reset. */
@@ -634,6 +650,11 @@ static void dummy_flush_queue_iso(struct fw_iso_context *ctx)
{
}

static int dummy_flush_iso_completions(struct fw_iso_context *ctx)
{
	return -ENODEV;
}

static const struct fw_card_driver dummy_driver_template = {
	.read_phy_reg		= dummy_read_phy_reg,
	.update_phy_reg		= dummy_update_phy_reg,
@@ -646,6 +667,7 @@ static const struct fw_card_driver dummy_driver_template = {
	.set_iso_channels	= dummy_set_iso_channels,
	.queue_iso		= dummy_queue_iso,
	.flush_queue_iso	= dummy_flush_queue_iso,
	.flush_iso_completions	= dummy_flush_iso_completions,
};

void fw_card_release(struct kref *kref)
+18 −6
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@
/*
 * ABI version history is documented in linux/firewire-cdev.h.
 */
#define FW_CDEV_KERNEL_VERSION			4
#define FW_CDEV_KERNEL_VERSION			5
#define FW_CDEV_VERSION_EVENT_REQUEST2		4
#define FW_CDEV_VERSION_ALLOCATE_REGION_END	4

@@ -389,7 +389,7 @@ static void queue_bus_reset_event(struct client *client)

	e = kzalloc(sizeof(*e), GFP_KERNEL);
	if (e == NULL) {
		fw_notify("Out of memory when allocating event\n");
		fw_notice(client->device->card, "out of memory when allocating event\n");
		return;
	}

@@ -438,6 +438,7 @@ union ioctl_arg {
	struct fw_cdev_send_phy_packet		send_phy_packet;
	struct fw_cdev_receive_phy_packets	receive_phy_packets;
	struct fw_cdev_set_iso_channels		set_iso_channels;
	struct fw_cdev_flush_iso		flush_iso;
};

static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
@@ -691,7 +692,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
	r = kmalloc(sizeof(*r), GFP_ATOMIC);
	e = kmalloc(sizeof(*e), GFP_ATOMIC);
	if (r == NULL || e == NULL) {
		fw_notify("Out of memory when allocating event\n");
		fw_notice(card, "out of memory when allocating event\n");
		goto failed;
	}
	r->card    = card;
@@ -928,7 +929,7 @@ static void iso_callback(struct fw_iso_context *context, u32 cycle,

	e = kmalloc(sizeof(*e) + header_length, GFP_ATOMIC);
	if (e == NULL) {
		fw_notify("Out of memory when allocating event\n");
		fw_notice(context->card, "out of memory when allocating event\n");
		return;
	}
	e->interrupt.type      = FW_CDEV_EVENT_ISO_INTERRUPT;
@@ -948,7 +949,7 @@ static void iso_mc_callback(struct fw_iso_context *context,

	e = kmalloc(sizeof(*e), GFP_ATOMIC);
	if (e == NULL) {
		fw_notify("Out of memory when allocating event\n");
		fw_notice(context->card, "out of memory when allocating event\n");
		return;
	}
	e->interrupt.type      = FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL;
@@ -1168,6 +1169,16 @@ static int ioctl_stop_iso(struct client *client, union ioctl_arg *arg)
	return fw_iso_context_stop(client->iso_context);
}

static int ioctl_flush_iso(struct client *client, union ioctl_arg *arg)
{
	struct fw_cdev_flush_iso *a = &arg->flush_iso;

	if (client->iso_context == NULL || a->handle != 0)
		return -EINVAL;

	return fw_iso_context_flush_completions(client->iso_context);
}

static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
{
	struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2;
@@ -1548,7 +1559,7 @@ void fw_cdev_handle_phy_packet(struct fw_card *card, struct fw_packet *p)
	list_for_each_entry(client, &card->phy_receiver_list, phy_receiver_link) {
		e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC);
		if (e == NULL) {
			fw_notify("Out of memory when allocating event\n");
			fw_notice(card, "out of memory when allocating event\n");
			break;
		}
		e->phy_packet.closure	= client->phy_receiver_closure;
@@ -1589,6 +1600,7 @@ static int (* const ioctl_handlers[])(struct client *, union ioctl_arg *) = {
	[0x15] = ioctl_send_phy_packet,
	[0x16] = ioctl_receive_phy_packets,
	[0x17] = ioctl_set_iso_channels,
	[0x18] = ioctl_flush_iso,
};

static int dispatch_ioctl(struct client *client,
+30 −32
Original line number Diff line number Diff line
@@ -485,6 +485,7 @@ static int read_rom(struct fw_device *device,
 */
static int read_config_rom(struct fw_device *device, int generation)
{
	struct fw_card *card = device->card;
	const u32 *old_rom, *new_rom;
	u32 *rom, *stack;
	u32 sp, key;
@@ -529,12 +530,12 @@ static int read_config_rom(struct fw_device *device, int generation)
	 */
	if ((rom[2] & 0x7) < device->max_speed ||
	    device->max_speed == SCODE_BETA ||
	    device->card->beta_repeaters_present) {
	    card->beta_repeaters_present) {
		u32 dummy;

		/* for S1600 and S3200 */
		if (device->max_speed == SCODE_BETA)
			device->max_speed = device->card->link_speed;
			device->max_speed = card->link_speed;

		while (device->max_speed > SCODE_100) {
			if (read_rom(device, generation, 0, &dummy) ==
@@ -576,7 +577,7 @@ static int read_config_rom(struct fw_device *device, int generation)
			 * a firmware bug.  Ignore this whole block, i.e.
			 * simply set a fake block length of 0.
			 */
			fw_error("skipped invalid ROM block %x at %llx\n",
			fw_err(card, "skipped invalid ROM block %x at %llx\n",
			       rom[i],
			       i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM);
			rom[i] = 0;
@@ -604,7 +605,8 @@ static int read_config_rom(struct fw_device *device, int generation)
			 * the ROM don't have to check offsets all the time.
			 */
			if (i + (rom[i] & 0xffffff) >= MAX_CONFIG_ROM_SIZE) {
				fw_error("skipped unsupported ROM entry %x at %llx\n",
				fw_err(card,
				       "skipped unsupported ROM entry %x at %llx\n",
				       rom[i],
				       i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM);
				rom[i] = 0;
@@ -641,6 +643,7 @@ static void fw_unit_release(struct device *dev)
{
	struct fw_unit *unit = fw_unit(dev);

	fw_device_put(fw_parent_device(unit));
	kfree(unit);
}

@@ -672,7 +675,7 @@ static void create_units(struct fw_device *device)
		 */
		unit = kzalloc(sizeof(*unit), GFP_KERNEL);
		if (unit == NULL) {
			fw_error("failed to allocate memory for unit\n");
			fw_err(device->card, "out of memory for unit\n");
			continue;
		}

@@ -692,6 +695,7 @@ static void create_units(struct fw_device *device)
		if (device_register(&unit->device) < 0)
			goto skip_unit;

		fw_device_get(device);
		continue;

	skip_unit:
@@ -873,7 +877,7 @@ static int lookup_existing_device(struct device *dev, void *data)
		smp_wmb();  /* update node_id before generation */
		old->generation = card->generation;
		old->config_rom_retries = 0;
		fw_notify("rediscovered device %s\n", dev_name(dev));
		fw_notice(card, "rediscovered device %s\n", dev_name(dev));

		PREPARE_DELAYED_WORK(&old->work, fw_device_update);
		fw_schedule_device_work(old, 0);
@@ -954,6 +958,7 @@ static void fw_device_init(struct work_struct *work)
{
	struct fw_device *device =
		container_of(work, struct fw_device, work.work);
	struct fw_card *card = device->card;
	struct device *revived_dev;
	int minor, ret;

@@ -970,16 +975,16 @@ static void fw_device_init(struct work_struct *work)
			fw_schedule_device_work(device, RETRY_DELAY);
		} else {
			if (device->node->link_on)
				fw_notify("giving up on config rom for node id %x\n",
				fw_notice(card, "giving up on Config ROM for node id %x\n",
					  device->node_id);
			if (device->node == device->card->root_node)
				fw_schedule_bm_work(device->card, 0);
			if (device->node == card->root_node)
				fw_schedule_bm_work(card, 0);
			fw_device_release(&device->device);
		}
		return;
	}

	revived_dev = device_find_child(device->card->device,
	revived_dev = device_find_child(card->device,
					device, lookup_existing_device);
	if (revived_dev) {
		put_device(revived_dev);
@@ -1002,7 +1007,7 @@ static void fw_device_init(struct work_struct *work)

	device->device.bus = &fw_bus_type;
	device->device.type = &fw_device_type;
	device->device.parent = device->card->device;
	device->device.parent = card->device;
	device->device.devt = MKDEV(fw_cdev_major, minor);
	dev_set_name(&device->device, "fw%d", minor);

@@ -1014,7 +1019,7 @@ static void fw_device_init(struct work_struct *work)
				&device->attribute_group);

	if (device_add(&device->device)) {
		fw_error("Failed to add device.\n");
		fw_err(card, "failed to add device\n");
		goto error_with_cdev;
	}

@@ -1035,15 +1040,7 @@ static void fw_device_init(struct work_struct *work)
		PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
		fw_schedule_device_work(device, SHUTDOWN_DELAY);
	} else {
		if (device->config_rom_retries)
			fw_notify("created device %s: GUID %08x%08x, S%d00, "
				  "%d config ROM retries\n",
				  dev_name(&device->device),
				  device->config_rom[3], device->config_rom[4],
				  1 << device->max_speed,
				  device->config_rom_retries);
		else
			fw_notify("created device %s: GUID %08x%08x, S%d00\n",
		fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n",
			  dev_name(&device->device),
			  device->config_rom[3], device->config_rom[4],
			  1 << device->max_speed);
@@ -1058,8 +1055,8 @@ static void fw_device_init(struct work_struct *work)
	 * just end up running the IRM work a couple of extra times -
	 * pretty harmless.
	 */
	if (device->node == device->card->root_node)
		fw_schedule_bm_work(device->card, 0);
	if (device->node == card->root_node)
		fw_schedule_bm_work(card, 0);

	return;

@@ -1163,12 +1160,13 @@ static void fw_device_refresh(struct work_struct *work)
			   FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
		goto gone;

	fw_notify("refreshed device %s\n", dev_name(&device->device));
	fw_notice(card, "refreshed device %s\n", dev_name(&device->device));
	device->config_rom_retries = 0;
	goto out;

 give_up:
	fw_notify("giving up on refresh of device %s\n", dev_name(&device->device));
	fw_notice(card, "giving up on refresh of device %s\n",
		  dev_name(&device->device));
 gone:
	atomic_set(&device->state, FW_DEVICE_GONE);
	PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
+6 −0
Original line number Diff line number Diff line
@@ -192,6 +192,12 @@ void fw_iso_context_queue_flush(struct fw_iso_context *ctx)
}
EXPORT_SYMBOL(fw_iso_context_queue_flush);

int fw_iso_context_flush_completions(struct fw_iso_context *ctx)
{
	return ctx->card->driver->flush_iso_completions(ctx);
}
EXPORT_SYMBOL(fw_iso_context_flush_completions);

int fw_iso_context_stop(struct fw_iso_context *ctx)
{
	return ctx->card->driver->stop_iso(ctx);
Loading