rx.c

来自「linux 内核源代码」· C语言 代码 · 共 656 行 · 第 1/2 页

C
656
字号
		struct POSTSTATUS {			__le32 Post_Command;			__le32 Post_Address;		} * post;		dma_addr_t paddr, baddr;		int ret;		if (likely((status & 0xFF000000L) == 0xBC000000L))			return (status >> 16) & 0xFF;		buffer = pci_alloc_consistent(dev->pdev, 512, &baddr);		ret = -2;		if (unlikely(buffer == NULL))			return ret;		post = pci_alloc_consistent(dev->pdev,		  sizeof(struct POSTSTATUS), &paddr);		if (unlikely(post == NULL)) {			pci_free_consistent(dev->pdev, 512, buffer, baddr);			return ret;		}		memset(buffer, 0, 512);		post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);		post->Post_Address = cpu_to_le32(baddr);		rx_writel(dev, MUnit.IMRx[0], paddr);		rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0,		  NULL, NULL, NULL, NULL, NULL);		pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS),		  post, paddr);		if (likely((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X')))) {			ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10);			ret <<= 4;			ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10);		}		pci_free_consistent(dev->pdev, 512, buffer, baddr);		return ret;	}	/*	 *	Wait for the adapter to be up and running.	 */	if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))		return -3;	/*	 *	Everything is OK	 */	return 0;}/** *	aac_rx_deliver_producer *	@fib: fib to issue * *	Will send a fib, returning 0 if successful. */int aac_rx_deliver_producer(struct fib * fib){	struct aac_dev *dev = fib->dev;	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];	unsigned long qflags;	u32 Index;	unsigned long nointr = 0;	spin_lock_irqsave(q->lock, qflags);	aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr);	q->numpending++;	*(q->headers.producer) = cpu_to_le32(Index + 1);	spin_unlock_irqrestore(q->lock, qflags);	if (!(nointr & aac_config.irq_mod))		aac_adapter_notify(dev, AdapNormCmdQueue);	return 0;}/** *	aac_rx_deliver_message *	@fib: fib to issue * *	Will send a fib, returning 0 if successful. */static int aac_rx_deliver_message(struct fib * fib){	struct aac_dev *dev = fib->dev;	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];	unsigned long qflags;	u32 Index;	u64 addr;	volatile void __iomem *device;	unsigned long count = 10000000L; /* 50 seconds */	spin_lock_irqsave(q->lock, qflags);	q->numpending++;	spin_unlock_irqrestore(q->lock, qflags);	for(;;) {		Index = rx_readl(dev, MUnit.InboundQueue);		if (unlikely(Index == 0xFFFFFFFFL))			Index = rx_readl(dev, MUnit.InboundQueue);		if (likely(Index != 0xFFFFFFFFL))			break;		if (--count == 0) {			spin_lock_irqsave(q->lock, qflags);			q->numpending--;			spin_unlock_irqrestore(q->lock, qflags);			return -ETIMEDOUT;		}		udelay(5);	}	device = dev->base + Index;	addr = fib->hw_fib_pa;	writel((u32)(addr & 0xffffffff), device);	device += sizeof(u32);	writel((u32)(addr >> 32), device);	device += sizeof(u32);	writel(le16_to_cpu(fib->hw_fib_va->header.Size), device);	rx_writel(dev, MUnit.InboundQueue, Index);	return 0;}/** *	aac_rx_ioremap *	@size: mapping resize request * */static int aac_rx_ioremap(struct aac_dev * dev, u32 size){	if (!size) {		iounmap(dev->regs.rx);		return 0;	}	dev->base = dev->regs.rx = ioremap(dev->scsi_host_ptr->base, size);	if (dev->base == NULL)		return -1;	dev->IndexRegs = &dev->regs.rx->IndexRegs;	return 0;}static int aac_rx_restart_adapter(struct aac_dev *dev, int bled){	u32 var;	if (!(dev->supplement_adapter_info.SupportedOptions2 &	  le32_to_cpu(AAC_OPTION_MU_RESET)) || (bled >= 0) || (bled == -2)) {		if (bled)			printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",				dev->name, dev->id, bled);		else {			bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,			  0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);			if (!bled && (var != 0x00000001) && (var != 0x3803000F))				bled = -EINVAL;		}		if (bled && (bled != -ETIMEDOUT))			bled = aac_adapter_sync_cmd(dev, IOP_RESET,			  0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);		if (bled && (bled != -ETIMEDOUT))			return -EINVAL;	}	if (bled || (var == 0x3803000F)) { /* USE_OTHER_METHOD */		rx_writel(dev, MUnit.reserved2, 3);		msleep(5000); /* Delay 5 seconds */		var = 0x00000001;	}	if (var != 0x00000001)		return -EINVAL;	if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)		return -ENODEV;	if (startup_timeout < 300)		startup_timeout = 300;	return 0;}/** *	aac_rx_select_comm	-	Select communications method *	@dev: Adapter *	@comm: communications method */int aac_rx_select_comm(struct aac_dev *dev, int comm){	switch (comm) {	case AAC_COMM_PRODUCER:		dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_producer;		dev->a_ops.adapter_intr = aac_rx_intr_producer;		dev->a_ops.adapter_deliver = aac_rx_deliver_producer;		break;	case AAC_COMM_MESSAGE:		dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_message;		dev->a_ops.adapter_intr = aac_rx_intr_message;		dev->a_ops.adapter_deliver = aac_rx_deliver_message;		break;	default:		return 1;	}	return 0;}/** *	aac_rx_init	-	initialize an i960 based AAC card *	@dev: device to configure * *	Allocate and set up resources for the i960 based AAC variants. The  *	device_interface in the commregion will be allocated and linked  *	to the comm region. */int _aac_rx_init(struct aac_dev *dev){	unsigned long start;	unsigned long status;	int restart = 0;	int instance = dev->id;	const char * name = dev->name;	if (aac_adapter_ioremap(dev, dev->base_size)) {		printk(KERN_WARNING "%s: unable to map adapter.\n", name);		goto error_iounmap;	}	/* Failure to reset here is an option ... */	dev->a_ops.adapter_sync_cmd = rx_sync_cmd;	dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;	dev->OIMR = status = rx_readb (dev, MUnit.OIMR);	if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&	  !aac_rx_restart_adapter(dev, 0))		++restart;	/*	 *	Check to see if the board panic'd while booting.	 */	status = rx_readl(dev, MUnit.OMRx[0]);	if (status & KERNEL_PANIC) {		if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))			goto error_iounmap;		++restart;	}	/*	 *	Check to see if the board failed any self tests.	 */	status = rx_readl(dev, MUnit.OMRx[0]);	if (status & SELF_TEST_FAILED) {		printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);		goto error_iounmap;	}	/*	 *	Check to see if the monitor panic'd while booting.	 */	if (status & MONITOR_PANIC) {		printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);		goto error_iounmap;	}	start = jiffies;	/*	 *	Wait for the adapter to be up and running. Wait up to 3 minutes	 */	while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING))	{		if ((restart &&		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||		  time_after(jiffies, start+HZ*startup_timeout)) {			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 					dev->name, instance, status);			goto error_iounmap;		}		if (!restart &&		  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||		  time_after(jiffies, start + HZ *		  ((startup_timeout > 60)		    ? (startup_timeout - 60)		    : (startup_timeout / 2))))) {			if (likely(!aac_rx_restart_adapter(dev, aac_rx_check_health(dev))))				start = jiffies;			++restart;		}		msleep(1);	}	if (restart && aac_commit)		aac_commit = 1;	/*	 *	Fill in the common function dispatch table.	 */	dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;	dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;	dev->a_ops.adapter_notify = aac_rx_notify_adapter;	dev->a_ops.adapter_sync_cmd = rx_sync_cmd;	dev->a_ops.adapter_check_health = aac_rx_check_health;	dev->a_ops.adapter_restart = aac_rx_restart_adapter;	/*	 *	First clear out all interrupts.  Then enable the one's that we	 *	can handle.	 */	aac_adapter_comm(dev, AAC_COMM_PRODUCER);	aac_adapter_disable_int(dev);	rx_writel(dev, MUnit.ODR, 0xffffffff);	aac_adapter_enable_int(dev);	if (aac_init_adapter(dev) == NULL)		goto error_iounmap;	aac_adapter_comm(dev, dev->comm_interface);	if (request_irq(dev->scsi_host_ptr->irq, dev->a_ops.adapter_intr,			IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {		printk(KERN_ERR "%s%d: Interrupt unavailable.\n",			name, instance);		goto error_iounmap;	}	aac_adapter_enable_int(dev);	/*	 *	Tell the adapter that all is configured, and it can	 * start accepting requests	 */	aac_rx_start_adapter(dev);	return 0;error_iounmap:	return -1;}int aac_rx_init(struct aac_dev *dev){	/*	 *	Fill in the function dispatch table.	 */	dev->a_ops.adapter_ioremap = aac_rx_ioremap;	dev->a_ops.adapter_comm = aac_rx_select_comm;	return _aac_rx_init(dev);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?