diff options
Diffstat (limited to 'drivers/firewire')
| -rw-r--r-- | drivers/firewire/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/firewire/core-device.c | 22 | ||||
| -rw-r--r-- | drivers/firewire/core-transaction.c | 8 | ||||
| -rw-r--r-- | drivers/firewire/core.h | 4 | ||||
| -rw-r--r-- | drivers/firewire/net.c | 10 | ||||
| -rw-r--r-- | drivers/firewire/ohci.c | 51 | ||||
| -rw-r--r-- | drivers/firewire/sbp2.c | 17 | 
7 files changed, 68 insertions, 47 deletions
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 7a701a58bbf..145974f9662 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -1,5 +1,6 @@  menu "IEEE 1394 (FireWire) support" -	depends on PCI || BROKEN +	depends on HAS_DMA +	depends on PCI || COMPILE_TEST  	# firewire-core does not depend on PCI but is  	# not useful without PCI controller driver diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index de4aa409abe..2c6d5e118ac 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -916,7 +916,7 @@ static int lookup_existing_device(struct device *dev, void *data)  		old->config_rom_retries = 0;  		fw_notice(card, "rediscovered device %s\n", dev_name(dev)); -		PREPARE_DELAYED_WORK(&old->work, fw_device_update); +		old->workfn = fw_device_update;  		fw_schedule_device_work(old, 0);  		if (current_node == card->root_node) @@ -1075,7 +1075,7 @@ static void fw_device_init(struct work_struct *work)  	if (atomic_cmpxchg(&device->state,  			   FW_DEVICE_INITIALIZING,  			   FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { -		PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); +		device->workfn = fw_device_shutdown;  		fw_schedule_device_work(device, SHUTDOWN_DELAY);  	} else {  		fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n", @@ -1196,13 +1196,20 @@ static void fw_device_refresh(struct work_struct *work)  		  dev_name(&device->device), fw_rcode_string(ret));   gone:  	atomic_set(&device->state, FW_DEVICE_GONE); -	PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); +	device->workfn = fw_device_shutdown;  	fw_schedule_device_work(device, SHUTDOWN_DELAY);   out:  	if (node_id == card->root_node->node_id)  		fw_schedule_bm_work(card, 0);  } +static void fw_device_workfn(struct work_struct *work) +{ +	struct fw_device *device = container_of(to_delayed_work(work), +						struct fw_device, work); +	device->workfn(work); +} +  void fw_node_event(struct fw_card *card, struct fw_node *node, int event)  {  	struct fw_device *device; @@ -1252,7 +1259,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)  		 * power-up after getting plugged in.  We schedule the  		 * first config rom scan half a second after bus reset.  		 */ -		INIT_DELAYED_WORK(&device->work, fw_device_init); +		device->workfn = fw_device_init; +		INIT_DELAYED_WORK(&device->work, fw_device_workfn);  		fw_schedule_device_work(device, INITIAL_DELAY);  		break; @@ -1268,7 +1276,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)  		if (atomic_cmpxchg(&device->state,  			    FW_DEVICE_RUNNING,  			    FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { -			PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); +			device->workfn = fw_device_refresh;  			fw_schedule_device_work(device,  				device->is_local ? 0 : INITIAL_DELAY);  		} @@ -1283,7 +1291,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)  		smp_wmb();  /* update node_id before generation */  		device->generation = card->generation;  		if (atomic_read(&device->state) == FW_DEVICE_RUNNING) { -			PREPARE_DELAYED_WORK(&device->work, fw_device_update); +			device->workfn = fw_device_update;  			fw_schedule_device_work(device, 0);  		}  		break; @@ -1308,7 +1316,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)  		device = node->data;  		if (atomic_xchg(&device->state,  				FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { -			PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); +			device->workfn = fw_device_shutdown;  			fw_schedule_device_work(device,  				list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);  		} diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index e5af0e3a26e..eb6935c8ad9 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -477,7 +477,7 @@ void fw_send_phy_config(struct fw_card *card,  	phy_config_packet.header[1] = data;  	phy_config_packet.header[2] = ~data;  	phy_config_packet.generation = generation; -	INIT_COMPLETION(phy_config_done); +	reinit_completion(&phy_config_done);  	card->driver->send_request(card, &phy_config_packet);  	wait_for_completion_timeout(&phy_config_done, timeout); @@ -523,11 +523,11 @@ static DEFINE_SPINLOCK(address_handler_list_lock);  static LIST_HEAD(address_handler_list);  const struct fw_address_region fw_high_memory_region = -	{ .start = 0x000100000000ULL, .end = 0xffffe0000000ULL,  }; +	{ .start = FW_MAX_PHYSICAL_RANGE, .end = 0xffffe0000000ULL, };  EXPORT_SYMBOL(fw_high_memory_region);  static const struct fw_address_region low_memory_region = -	{ .start = 0x000000000000ULL, .end = 0x000100000000ULL,  }; +	{ .start = 0x000000000000ULL, .end = FW_MAX_PHYSICAL_RANGE, };  #if 0  const struct fw_address_region fw_private_region = @@ -1217,7 +1217,7 @@ static void handle_low_memory(struct fw_card *card, struct fw_request *request,  }  static struct fw_address_handler low_memory = { -	.length			= 0x000100000000ULL, +	.length			= FW_MAX_PHYSICAL_RANGE,  	.address_callback	= handle_low_memory,  }; diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index 515a42c786d..e1480ff683d 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -118,7 +118,6 @@ int fw_card_add(struct fw_card *card,  		u32 max_receive, u32 link_speed, u64 guid);  void fw_core_remove_card(struct fw_card *card);  int fw_compute_block_crc(__be32 *block); -void fw_schedule_bus_reset(struct fw_card *card, bool delayed, bool short_reset);  void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);  /* -cdev */ @@ -237,6 +236,9 @@ static inline bool is_next_generation(int new_generation, int old_generation)  #define LOCAL_BUS 0xffc0 +/* OHCI-1394's default upper bound for physical DMA: 4 GB */ +#define FW_MAX_PHYSICAL_RANGE		(1ULL << 32) +  void fw_core_handle_request(struct fw_card *card, struct fw_packet *request);  void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);  int fw_get_response_length(struct fw_request *request); diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 6b895986dc2..c3986452194 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -929,8 +929,6 @@ static void fwnet_write_complete(struct fw_card *card, int rcode,  	if (rcode == RCODE_COMPLETE) {  		fwnet_transmit_packet_done(ptask);  	} else { -		fwnet_transmit_packet_failed(ptask); -  		if (printk_timed_ratelimit(&j,  1000) || rcode != last_rcode) {  			dev_err(&ptask->dev->netdev->dev,  				"fwnet_write_complete failed: %x (skipped %d)\n", @@ -938,8 +936,10 @@ static void fwnet_write_complete(struct fw_card *card, int rcode,  			errors_skipped = 0;  			last_rcode = rcode; -		} else +		} else {  			errors_skipped++; +		} +		fwnet_transmit_packet_failed(ptask);  	}  } @@ -1462,8 +1462,8 @@ static int fwnet_probe(struct fw_unit *unit,  	net = alloc_netdev(sizeof(*dev), "firewire%d", fwnet_init_dev);  	if (net == NULL) { -		ret = -ENOMEM; -		goto out; +		mutex_unlock(&fwnet_device_mutex); +		return -ENOMEM;  	}  	allocated_netdev = true; diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 6aa8a86cb83..a66a3217f1d 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -282,6 +282,7 @@ static char ohci_driver_name[] = KBUILD_MODNAME;  #define PCI_DEVICE_ID_TI_TSB82AA2	0x8025  #define PCI_DEVICE_ID_VIA_VT630X	0x3044  #define PCI_REV_ID_VIA_VT6306		0x46 +#define PCI_DEVICE_ID_VIA_VT6315	0x3403  #define QUIRK_CYCLE_TIMER		0x1  #define QUIRK_RESET_PACKET		0x2 @@ -290,7 +291,6 @@ static char ohci_driver_name[] = KBUILD_MODNAME;  #define QUIRK_NO_MSI			0x10  #define QUIRK_TI_SLLZ059		0x20  #define QUIRK_IR_WAKE			0x40 -#define QUIRK_PHY_LCTRL_TIMEOUT		0x80  /* In case of multiple matches in ohci_quirks[], only the first one is used. */  static const struct { @@ -303,10 +303,7 @@ static const struct {  		QUIRK_BE_HEADERS},  	{PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, -		QUIRK_PHY_LCTRL_TIMEOUT | QUIRK_NO_MSI}, - -	{PCI_VENDOR_ID_ATT, PCI_ANY_ID, PCI_ANY_ID, -		QUIRK_PHY_LCTRL_TIMEOUT}, +		QUIRK_NO_MSI},  	{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID,  		QUIRK_RESET_PACKET}, @@ -338,6 +335,12 @@ static const struct {  	{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT630X, PCI_REV_ID_VIA_VT6306,  		QUIRK_CYCLE_TIMER | QUIRK_IR_WAKE}, +	{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT6315, 0, +		QUIRK_CYCLE_TIMER /* FIXME: necessary? */ | QUIRK_NO_MSI}, + +	{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT6315, PCI_ANY_ID, +		QUIRK_NO_MSI}, +  	{PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,  		QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},  }; @@ -353,7 +356,6 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"  	", disable MSI = "		__stringify(QUIRK_NO_MSI)  	", TI SLLZ059 erratum = "	__stringify(QUIRK_TI_SLLZ059)  	", IR wake unreliable = "	__stringify(QUIRK_IR_WAKE) -	", phy LCtrl timeout = "	__stringify(QUIRK_PHY_LCTRL_TIMEOUT)  	")");  #define OHCI_PARAM_DEBUG_AT_AR		1 @@ -370,6 +372,10 @@ MODULE_PARM_DESC(debug, "Verbose logging (default = 0"  	", busReset events = "	__stringify(OHCI_PARAM_DEBUG_BUSRESETS)  	", or a combination, or all = -1)"); +static bool param_remote_dma; +module_param_named(remote_dma, param_remote_dma, bool, 0444); +MODULE_PARM_DESC(remote_dma, "Enable unfiltered remote DMA (default = N)"); +  static void log_irqs(struct fw_ohci *ohci, u32 evt)  {  	if (likely(!(param_debug & @@ -2050,10 +2056,10 @@ static void bus_reset_work(struct work_struct *work)  			  be32_to_cpu(ohci->next_header));  	} -#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA -	reg_write(ohci, OHCI1394_PhyReqFilterHiSet, ~0); -	reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0); -#endif +	if (param_remote_dma) { +		reg_write(ohci, OHCI1394_PhyReqFilterHiSet, ~0); +		reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0); +	}  	spin_unlock_irq(&ohci->lock); @@ -2295,9 +2301,6 @@ static int ohci_enable(struct fw_card *card,  	 * TI TSB82AA2 + TSB81BA3(A) cards signal LPS enabled early but  	 * cannot actually use the phy at that time.  These need tens of  	 * millisecods pause between LPS write and first phy access too. -	 * -	 * But do not wait for 50msec on Agere/LSI cards.  Their phy -	 * arbitration state machine may time out during such a long wait.  	 */  	reg_write(ohci, OHCI1394_HCControlSet, @@ -2305,11 +2308,8 @@ static int ohci_enable(struct fw_card *card,  		  OHCI1394_HCControl_postedWriteEnable);  	flush_writes(ohci); -	if (!(ohci->quirks & QUIRK_PHY_LCTRL_TIMEOUT)) +	for (lps = 0, i = 0; !lps && i < 3; i++) {  		msleep(50); - -	for (lps = 0, i = 0; !lps && i < 150; i++) { -		msleep(1);  		lps = reg_read(ohci, OHCI1394_HCControlSet) &  		      OHCI1394_HCControl_LPS;  	} @@ -2363,7 +2363,7 @@ static int ohci_enable(struct fw_card *card,  	reg_write(ohci, OHCI1394_FairnessControl, 0);  	card->priority_budget_implemented = ohci->pri_req_max != 0; -	reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000); +	reg_write(ohci, OHCI1394_PhyUpperBound, FW_MAX_PHYSICAL_RANGE >> 16);  	reg_write(ohci, OHCI1394_IntEventClear, ~0);  	reg_write(ohci, OHCI1394_IntMaskClear, ~0); @@ -2587,13 +2587,13 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)  static int ohci_enable_phys_dma(struct fw_card *card,  				int node_id, int generation)  { -#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA -	return 0; -#else  	struct fw_ohci *ohci = fw_ohci(card);  	unsigned long flags;  	int n, ret = 0; +	if (param_remote_dma) +		return 0; +  	/*  	 * FIXME:  Make sure this bitmask is cleared when we clear the busReset  	 * interrupt bit.  Clear physReqResourceAllBuses on bus reset. @@ -2622,7 +2622,6 @@ static int ohci_enable_phys_dma(struct fw_card *card,  	spin_unlock_irqrestore(&ohci->lock, flags);  	return ret; -#endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */  }  static u32 ohci_read_csr(struct fw_card *card, int csr_offset) @@ -3506,7 +3505,7 @@ static int ohci_flush_iso_completions(struct fw_iso_context *base)  		}  		clear_bit_unlock(0, &ctx->flushing_completions); -		smp_mb__after_clear_bit(); +		smp_mb__after_atomic();  	}  	tasklet_enable(&ctx->context.tasklet); @@ -3720,9 +3719,11 @@ static int pci_probe(struct pci_dev *dev,  	version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;  	ohci_notice(ohci,  		    "added OHCI v%x.%x device as card %d, " -		    "%d IR + %d IT contexts, quirks 0x%x\n", +		    "%d IR + %d IT contexts, quirks 0x%x%s\n",  		    version >> 16, version & 0xff, ohci->card.index, -		    ohci->n_ir, ohci->n_it, ohci->quirks); +		    ohci->n_ir, ohci->n_it, ohci->quirks, +		    reg_read(ohci, OHCI1394_PhyUpperBound) ? +			", physUB" : "");  	return 0; diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 281029daf98..7aef911fdc7 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -146,6 +146,7 @@ struct sbp2_logical_unit {  	 */  	int generation;  	int retries; +	work_func_t workfn;  	struct delayed_work work;  	bool has_sdev;  	bool blocked; @@ -864,7 +865,7 @@ static void sbp2_login(struct work_struct *work)  	/* set appropriate retry limit(s) in BUSY_TIMEOUT register */  	sbp2_set_busy_timeout(lu); -	PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); +	lu->workfn = sbp2_reconnect;  	sbp2_agent_reset(lu);  	/* This was a re-login. */ @@ -918,7 +919,7 @@ static void sbp2_login(struct work_struct *work)  	 * If a bus reset happened, sbp2_update will have requeued  	 * lu->work already.  Reset the work from reconnect to login.  	 */ -	PREPARE_DELAYED_WORK(&lu->work, sbp2_login); +	lu->workfn = sbp2_login;  }  static void sbp2_reconnect(struct work_struct *work) @@ -952,7 +953,7 @@ static void sbp2_reconnect(struct work_struct *work)  		    lu->retries++ >= 5) {  			dev_err(tgt_dev(tgt), "failed to reconnect\n");  			lu->retries = 0; -			PREPARE_DELAYED_WORK(&lu->work, sbp2_login); +			lu->workfn = sbp2_login;  		}  		sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); @@ -972,6 +973,13 @@ static void sbp2_reconnect(struct work_struct *work)  	sbp2_conditionally_unblock(lu);  } +static void sbp2_lu_workfn(struct work_struct *work) +{ +	struct sbp2_logical_unit *lu = container_of(to_delayed_work(work), +						struct sbp2_logical_unit, work); +	lu->workfn(work); +} +  static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)  {  	struct sbp2_logical_unit *lu; @@ -998,7 +1006,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)  	lu->blocked  = false;  	++tgt->dont_block;  	INIT_LIST_HEAD(&lu->orb_list); -	INIT_DELAYED_WORK(&lu->work, sbp2_login); +	lu->workfn = sbp2_login; +	INIT_DELAYED_WORK(&lu->work, sbp2_lu_workfn);  	list_add_tail(&lu->link, &tgt->lu_list);  	return 0;  | 
