亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ohci1394.c

?? Ieee1394驅動實現
?? C
?? 第 1 頁 / 共 5 頁
字號:
/*
 * ohci1394.c - driver for OHCI 1394 boards
 * Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
 *                        Gord Peters <GordPeters@smarttech.com>
 *              2001      Ben Collins <bcollins@debian.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

/*
 * Things known to be working:
 * . Async Request Transmit
 * . Async Response Receive
 * . Async Request Receive
 * . Async Response Transmit
 * . Iso Receive
 * . DMA mmap for iso receive
 * . Config ROM generation
 *
 * Things implemented, but still in test phase:
 * . Iso Transmit
 * . Async Stream Packets Transmit (Receive done via Iso interface)
 *
 * Things not implemented:
 * . DMA error recovery
 *
 * Known bugs:
 * . devctl BUS_RESET arg confusion (reset type or root holdoff?)
 *   added LONG_RESET_ROOT and SHORT_RESET_ROOT for root holdoff --kk
 */

/*
 * Acknowledgments:
 *
 * Adam J Richter <adam@yggdrasil.com>
 *  . Use of pci_class to find device
 *
 * Emilie Chung	<emilie.chung@axis.com>
 *  . Tip on Async Request Filter
 *
 * Pascal Drolet <pascal.drolet@informission.ca>
 *  . Various tips for optimization and functionnalities
 *
 * Robert Ficklin <rficklin@westengineering.com>
 *  . Loop in irq_handler
 *
 * James Goodwin <jamesg@Filanet.com>
 *  . Various tips on initialization, self-id reception, etc.
 *
 * Albrecht Dress <ad@mpifr-bonn.mpg.de>
 *  . Apple PowerBook detection
 *
 * Daniel Kobras <daniel.kobras@student.uni-tuebingen.de>
 *  . Reset the board properly before leaving + misc cleanups
 *
 * Leon van Stuivenberg <leonvs@iae.nl>
 *  . Bug fixes
 *
 * Ben Collins <bcollins@debian.org>
 *  . Working big-endian support
 *  . Updated to 2.4.x module scheme (PCI aswell)
 *  . Config ROM generation
 *
 * Manfred Weihs <weihs@ict.tuwien.ac.at>
 *  . Reworked code for initiating bus resets
 *    (long, short, with or without hold-off)
 *
 * Nandu Santhi <contactnandu@users.sourceforge.net>
 *  . Added support for nVidia nForce2 onboard Firewire chipset
 *
 */

#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include <linux/delay.h>
#include <linux/spinlock.h>

#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/irq.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <linux/init.h>

#ifdef CONFIG_PPC_PMAC
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#endif

#include "csr1212.h"
#include "ieee1394.h"
#include "ieee1394_types.h"
#include "hosts.h"
#include "dma.h"
#include "iso.h"
#include "ieee1394_core.h"
#include "highlevel.h"
#include "ohci1394.h"

#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
#define OHCI1394_DEBUG
#endif

#ifdef DBGMSG
#undef DBGMSG
#endif

#ifdef OHCI1394_DEBUG
#define DBGMSG(fmt, args...) \
printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
#else
#define DBGMSG(fmt, args...) do {} while (0)
#endif

/* print general (card independent) information */
#define PRINT_G(level, fmt, args...) \
printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)

/* print card specific information */
#define PRINT(level, fmt, args...) \
printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)

/* Module Parameters */
static int phys_dma = 1;
module_param(phys_dma, int, 0444);
MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");

static void dma_trm_tasklet(unsigned long data);
static void dma_trm_reset(struct dma_trm_ctx *d);

static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
			     enum context_type type, int ctx, int num_desc,
			     int buf_size, int split_buf_size, int context_base);
static void free_dma_rcv_ctx(struct dma_rcv_ctx *d);

static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
			     enum context_type type, int ctx, int num_desc,
			     int context_base);

static void ohci1394_pci_remove(struct pci_dev *pdev);

#ifndef __LITTLE_ENDIAN
static const size_t hdr_sizes[] = {
	3,	/* TCODE_WRITEQ */
	4,	/* TCODE_WRITEB */
	3,	/* TCODE_WRITE_RESPONSE */
	0,	/* reserved */
	3,	/* TCODE_READQ */
	4,	/* TCODE_READB */
	3,	/* TCODE_READQ_RESPONSE */
	4,	/* TCODE_READB_RESPONSE */
	1,	/* TCODE_CYCLE_START */
	4,	/* TCODE_LOCK_REQUEST */
	2,	/* TCODE_ISO_DATA */
	4,	/* TCODE_LOCK_RESPONSE */
		/* rest is reserved or link-internal */
};

static inline void header_le32_to_cpu(quadlet_t *data, unsigned char tcode)
{
	size_t size;

	if (unlikely(tcode >= ARRAY_SIZE(hdr_sizes)))
		return;

	size = hdr_sizes[tcode];
	while (size--)
		data[size] = le32_to_cpu(data[size]);
}
#else
#define header_le32_to_cpu(w,x) do {} while (0)
#endif /* !LITTLE_ENDIAN */

/***********************************
 * IEEE-1394 functionality section *
 ***********************************/

static u8 get_phy_reg(struct ti_ohci *ohci, u8 addr)
{
	int i;
	unsigned long flags;
	quadlet_t r;

	spin_lock_irqsave (&ohci->phy_reg_lock, flags);

	reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | 0x00008000);

	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
		if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000)
			break;

		mdelay(1);
	}

	r = reg_read(ohci, OHCI1394_PhyControl);

	if (i >= OHCI_LOOP_COUNT)
		PRINT (KERN_ERR, "Get PHY Reg timeout [0x%08x/0x%08x/%d]",
		       r, r & 0x80000000, i);

	spin_unlock_irqrestore (&ohci->phy_reg_lock, flags);

	return (r & 0x00ff0000) >> 16;
}

static void set_phy_reg(struct ti_ohci *ohci, u8 addr, u8 data)
{
	int i;
	unsigned long flags;
	u32 r = 0;

	spin_lock_irqsave (&ohci->phy_reg_lock, flags);

	reg_write(ohci, OHCI1394_PhyControl, (addr << 8) | data | 0x00004000);

	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
		r = reg_read(ohci, OHCI1394_PhyControl);
		if (!(r & 0x00004000))
			break;

		mdelay(1);
	}

	if (i == OHCI_LOOP_COUNT)
		PRINT (KERN_ERR, "Set PHY Reg timeout [0x%08x/0x%08x/%d]",
		       r, r & 0x00004000, i);

	spin_unlock_irqrestore (&ohci->phy_reg_lock, flags);

	return;
}

/* Or's our value into the current value */
static void set_phy_reg_mask(struct ti_ohci *ohci, u8 addr, u8 data)
{
	u8 old;

	old = get_phy_reg (ohci, addr);
	old |= data;
	set_phy_reg (ohci, addr, old);

	return;
}

static void handle_selfid(struct ti_ohci *ohci, struct hpsb_host *host,
				int phyid, int isroot)
{
	quadlet_t *q = ohci->selfid_buf_cpu;
	quadlet_t self_id_count=reg_read(ohci, OHCI1394_SelfIDCount);
	size_t size;
	quadlet_t q0, q1;

	/* Check status of self-id reception */

	if (ohci->selfid_swap)
		q0 = le32_to_cpu(q[0]);
	else
		q0 = q[0];

	if ((self_id_count & 0x80000000) ||
	    ((self_id_count & 0x00FF0000) != (q0 & 0x00FF0000))) {
		PRINT(KERN_ERR,
		      "Error in reception of SelfID packets [0x%08x/0x%08x] (count: %d)",
		      self_id_count, q0, ohci->self_id_errors);

		/* Tip by James Goodwin <jamesg@Filanet.com>:
		 * We had an error, generate another bus reset in response.  */
		if (ohci->self_id_errors<OHCI1394_MAX_SELF_ID_ERRORS) {
			set_phy_reg_mask (ohci, 1, 0x40);
			ohci->self_id_errors++;
		} else {
			PRINT(KERN_ERR,
			      "Too many errors on SelfID error reception, giving up!");
		}
		return;
	}

	/* SelfID Ok, reset error counter. */
	ohci->self_id_errors = 0;

	size = ((self_id_count & 0x00001FFC) >> 2) - 1;
	q++;

	while (size > 0) {
		if (ohci->selfid_swap) {
			q0 = le32_to_cpu(q[0]);
			q1 = le32_to_cpu(q[1]);
		} else {
			q0 = q[0];
			q1 = q[1];
		}

		if (q0 == ~q1) {
			DBGMSG ("SelfID packet 0x%x received", q0);
			hpsb_selfid_received(host, cpu_to_be32(q0));
			if (((q0 & 0x3f000000) >> 24) == phyid)
				DBGMSG ("SelfID for this node is 0x%08x", q0);
		} else {
			PRINT(KERN_ERR,
			      "SelfID is inconsistent [0x%08x/0x%08x]", q0, q1);
		}
		q += 2;
		size -= 2;
	}

	DBGMSG("SelfID complete");

	return;
}

static void ohci_soft_reset(struct ti_ohci *ohci) {
	int i;

	reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);

	for (i = 0; i < OHCI_LOOP_COUNT; i++) {
		if (!(reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_softReset))
			break;
		mdelay(1);
	}
	DBGMSG ("Soft reset finished");
}


/* Generate the dma receive prgs and start the context */
static void initialize_dma_rcv_ctx(struct dma_rcv_ctx *d, int generate_irq)
{
	struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
	int i;

	ohci1394_stop_context(ohci, d->ctrlClear, NULL);

	for (i=0; i<d->num_desc; i++) {
		u32 c;

		c = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | DMA_CTL_BRANCH;
		if (generate_irq)
			c |= DMA_CTL_IRQ;

		d->prg_cpu[i]->control = cpu_to_le32(c | d->buf_size);

		/* End of descriptor list? */
		if (i + 1 < d->num_desc) {
			d->prg_cpu[i]->branchAddress =
				cpu_to_le32((d->prg_bus[i+1] & 0xfffffff0) | 0x1);
		} else {
			d->prg_cpu[i]->branchAddress =
				cpu_to_le32((d->prg_bus[0] & 0xfffffff0));
		}

		d->prg_cpu[i]->address = cpu_to_le32(d->buf_bus[i]);
		d->prg_cpu[i]->status = cpu_to_le32(d->buf_size);
	}

        d->buf_ind = 0;
        d->buf_offset = 0;

	if (d->type == DMA_CTX_ISO) {
		/* Clear contextControl */
		reg_write(ohci, d->ctrlClear, 0xffffffff);

		/* Set bufferFill, isochHeader, multichannel for IR context */
		reg_write(ohci, d->ctrlSet, 0xd0000000);

		/* Set the context match register to match on all tags */
		reg_write(ohci, d->ctxtMatch, 0xf0000000);

		/* Clear the multi channel mask high and low registers */
		reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear, 0xffffffff);
		reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear, 0xffffffff);

		/* Set up isoRecvIntMask to generate interrupts */
		reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << d->ctx);
	}

	/* Tell the controller where the first AR program is */
	reg_write(ohci, d->cmdPtr, d->prg_bus[0] | 0x1);

	/* Run context */
	reg_write(ohci, d->ctrlSet, 0x00008000);

	DBGMSG("Receive DMA ctx=%d initialized", d->ctx);
}

/* Initialize the dma transmit context */
static void initialize_dma_trm_ctx(struct dma_trm_ctx *d)
{
	struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);

	/* Stop the context */
	ohci1394_stop_context(ohci, d->ctrlClear, NULL);

        d->prg_ind = 0;
	d->sent_ind = 0;
	d->free_prgs = d->num_desc;
        d->branchAddrPtr = NULL;
	INIT_LIST_HEAD(&d->fifo_list);
	INIT_LIST_HEAD(&d->pending_list);

	if (d->type == DMA_CTX_ISO) {
		/* enable interrupts */
		reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << d->ctx);
	}

	DBGMSG("Transmit DMA ctx=%d initialized", d->ctx);
}

/* Count the number of available iso contexts */
static int get_nb_iso_ctx(struct ti_ohci *ohci, int reg)
{
	int i,ctx=0;
	u32 tmp;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久99久精品视频免费观看| 国产精品看片你懂得| 国产精品66部| 亚洲免费观看高清| 精品盗摄一区二区三区| 不卡一二三区首页| 另类综合日韩欧美亚洲| 亚洲男同1069视频| 中文字幕国产一区二区| 欧美一级高清大全免费观看| 色噜噜狠狠色综合欧洲selulu| 奇米综合一区二区三区精品视频| 亚洲精品视频在线看| 国产日韩欧美制服另类| 蜜臀99久久精品久久久久久软件| 中文字幕制服丝袜成人av| 久久一二三国产| 精品国产乱码久久久久久闺蜜| 欧美精品丝袜久久久中文字幕| 一本色道久久加勒比精品| 国产成人丝袜美腿| 国产精品主播直播| 久久精品国产在热久久| 日本在线不卡视频一二三区| 日韩国产在线一| 久久精品国产精品亚洲红杏 | 久久国产精品一区二区| 五月综合激情日本mⅴ| 亚洲国产精品久久久久秋霞影院| 亚洲免费观看高清完整版在线观看| 亚洲欧美自拍偷拍色图| 亚洲少妇最新在线视频| 亚洲精品国产一区二区精华液| 又紧又大又爽精品一区二区| 亚洲小说春色综合另类电影| 亚洲国产日日夜夜| 欧美成人福利视频| 久久久久久久久99精品| 亚洲视频每日更新| 偷拍自拍另类欧美| 国产一区二区三区美女| 色哟哟精品一区| 亚洲一区二区五区| 日韩国产一区二| 成人性生交大片| 欧美一级生活片| 国产精品九色蝌蚪自拍| 亚洲自拍偷拍九九九| 久久成人免费电影| 欧洲av一区二区嗯嗯嗯啊| 亚洲另类春色校园小说| 美日韩一区二区| 欧美视频一区在线| 精品国产乱码久久| 欧美日韩一区小说| 国产日产亚洲精品系列| 婷婷六月综合亚洲| 国产精品美女久久久久久2018 | 国产一区二区三区观看| 欧美私人免费视频| 日韩理论片一区二区| 国产真实乱对白精彩久久| 欧美色网一区二区| 亚洲日本成人在线观看| 国产成人午夜精品影院观看视频 | 日韩精品欧美成人高清一区二区| 精品亚洲成a人| 欧美人与禽zozo性伦| 亚洲综合精品自拍| 91老师国产黑色丝袜在线| 国产精品网友自拍| 欧美经典一区二区| 国产精品美女久久久久久久| 日韩精品一级中文字幕精品视频免费观看 | 欧美日韩国产系列| 欧美国产视频在线| 国产99久久久国产精品| 亚洲国产精品成人综合| 国产精品18久久久久久久久久久久| 精品免费视频一区二区| 国产一区二区三区综合| 中日韩av电影| 91久久精品一区二区| 一级精品视频在线观看宜春院| 色综合久久中文综合久久97 | 国产乱码精品1区2区3区| 久久综合久久鬼色| 成人18精品视频| 亚洲大片免费看| 欧美一区二区三区色| 国产福利一区二区三区在线视频| 国产女同互慰高潮91漫画| 色综合婷婷久久| 青青草国产成人av片免费| 久久精品夜色噜噜亚洲aⅴ| 91伊人久久大香线蕉| 首页国产欧美久久| 国产精品色哟哟| 日韩一区二区三区免费观看| 国产成人在线影院 | 日韩av在线免费观看不卡| 国产人妖乱国产精品人妖| 欧美性猛片xxxx免费看久爱| 毛片av一区二区| 亚洲一区免费在线观看| 国产日产欧美一区二区三区| 91在线观看下载| 黑人巨大精品欧美黑白配亚洲| 亚洲人成人一区二区在线观看| 欧美xxxxxxxxx| 欧美日韩亚洲综合一区二区三区| 国产不卡在线一区| 毛片一区二区三区| 午夜亚洲福利老司机| 亚洲婷婷在线视频| 亚洲欧洲成人精品av97| 26uuu国产在线精品一区二区| 欧美日韩大陆一区二区| 欧美亚洲精品一区| 色婷婷av久久久久久久| www.亚洲在线| 91丨九色丨黑人外教| 懂色av一区二区夜夜嗨| 狠狠色综合播放一区二区| 日本vs亚洲vs韩国一区三区| 午夜a成v人精品| 日本亚洲欧美天堂免费| 免费高清成人在线| 麻豆国产精品官网| 激情六月婷婷综合| 国产激情偷乱视频一区二区三区 | 久久精品免费观看| 极品少妇一区二区| 成人激情免费视频| 91同城在线观看| 91福利国产精品| 欧美一区二区免费| 欧美成人一区二区三区片免费| 久久综合网色—综合色88| 国产日本亚洲高清| 亚洲一二三区不卡| 加勒比av一区二区| 91美女片黄在线观看| 欧美日韩免费视频| 久久嫩草精品久久久精品| 国产精品第一页第二页第三页| 亚洲黄色录像片| 久久99精品久久久| 色综合久久综合网| 日韩欧美另类在线| 色婷婷综合久久| 色琪琪一区二区三区亚洲区| 91蜜桃免费观看视频| 欧美不卡一区二区| 一区二区高清在线| 激情国产一区二区| 欧洲视频一区二区| 久久久国产综合精品女国产盗摄| 日韩美女视频一区| 久久91精品久久久久久秒播| 91在线国内视频| 国产调教视频一区| 麻豆国产精品777777在线| 在线一区二区视频| 日本一区二区视频在线观看| 亚洲mv在线观看| 91老师国产黑色丝袜在线| 国产精品美女久久久久久久网站| 久久精品国产精品青草| 91精品国产全国免费观看| 一卡二卡三卡日韩欧美| 91视频com| 亚洲日本韩国一区| 99re这里都是精品| 国产精品天美传媒| 不卡一区二区在线| 亚洲欧美另类在线| 色婷婷久久一区二区三区麻豆| 国产精品久久久久久亚洲毛片| 国产在线国偷精品免费看| 欧美www视频| 极品少妇xxxx精品少妇偷拍| 久久蜜桃av一区精品变态类天堂| 奇米色777欧美一区二区| 日韩免费性生活视频播放| 精品一区二区三区免费观看| 精品国产乱码久久| av一区二区三区在线| 亚洲天堂av老司机| 欧美日韩成人一区二区| 青青青伊人色综合久久| 国产日韩欧美电影| 日本国产一区二区| 美女视频一区在线观看| 久久影院午夜片一区| 97aⅴ精品视频一二三区| 无码av免费一区二区三区试看| 精品区一区二区| 色呦呦国产精品| 国产麻豆精品视频|