/*
 * free all resources used by the channels and switch off leds and can power
 */
static void pcan_free_channels(struct pcan_pccard *card)
{
	int i;
	u8 led_mask = 0;

	for (i = 0; i < card->chan_count; i++) {
		struct net_device *netdev;
		char name[IFNAMSIZ];

		led_mask |= PCC_LED(i);

		netdev = card->channel[i].netdev;
		if (!netdev)
			continue;

		strncpy(name, netdev->name, IFNAMSIZ);

		unregister_sja1000dev(netdev);

		free_sja1000dev(netdev);

		dev_info(&card->pdev->dev, "%s removed\n", name);
	}

	/* do it only if device not removed */
	if (pcan_pccard_present(card)) {
		pcan_set_leds(card, led_mask, PCC_LED_OFF);
		pcan_set_can_power(card, 0);
	}
}
static irqreturn_t pcan_isr(int irq, void *dev_id)
{
	struct pcan_pccard *card = dev_id;
	int irq_handled;

	
	for (irq_handled = 0; irq_handled < PCC_ISR_MAX_LOOP; irq_handled++) {
		
		int nothing_to_handle = 1;
		int i;

		
		for (i = 0; i < card->chan_count; i++) {
			struct net_device *netdev;

			if (!pcan_pccard_present(card)) {
				
				return IRQ_NONE;
			}

			netdev = card->channel[i].netdev;
			if (netdev &&
			    sja1000_interrupt(irq, netdev) == IRQ_HANDLED)
				nothing_to_handle = 0;
		}

		if (nothing_to_handle)
			break;
	}

	return (irq_handled) ? IRQ_HANDLED : IRQ_NONE;
}
/*
 * interrupt service routine
 */
static irqreturn_t pcan_isr(int irq, void *dev_id)
{
	struct pcan_pccard *card = dev_id;
	int irq_handled;

	/* prevent from infinite loop */
	for (irq_handled = 0; irq_handled < PCC_ISR_MAX_LOOP; irq_handled++) {
		/* handle shared interrupt and next loop */
		int nothing_to_handle = 1;
		int i;

		/* check interrupt for each channel */
		for (i = 0; i < card->chan_count; i++) {
			struct net_device *netdev;

			/*
			 * check whether the card is present before calling
			 * sja1000_interrupt() to speed up hotplug detection
			 */
			if (!pcan_pccard_present(card)) {
				/* card unplugged during isr */
				return IRQ_NONE;
			}

			/*
			 * should check whether all or SJA1000_MAX_IRQ
			 * interrupts have been handled: loop again to be sure.
			 */
			netdev = card->channel[i].netdev;
			if (netdev &&
			    sja1000_interrupt(irq, netdev) == IRQ_HANDLED)
				nothing_to_handle = 0;
		}

		if (nothing_to_handle)
			break;
	}

	return (irq_handled) ? IRQ_HANDLED : IRQ_NONE;
}