⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ohci1394.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				       == 0x11) ? 1 : 0;				hpsb_packet_received(ohci->host, buf_ptr, 						     length, ack);			}			else 				PRINT(KERN_INFO, ohci->id, 				      "Got phy packet ctx=%d ... discarded",				      d->ctx);			offset += length;			buf_ptr += length/4;			if (offset==d->buf_size) {				insert_dma_buffer(d, idx);				idx = (idx+1) % d->num_desc;				buf_ptr = d->buf_cpu[idx];				offset=0;			}		}		rescount = d->prg_cpu[idx]->status & 0xffff;		bytes_left = d->buf_size - rescount - offset;	}	d->buf_ind = idx;	d->buf_offset = offset;	spin_unlock(&d->lock);}/* Bottom half that processes sent packets */static void dma_trm_bh(void *data){	struct dma_trm_ctx *d = (struct dma_trm_ctx*)data;	struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);	struct hpsb_packet *packet, *nextpacket;	unsigned long flags;	u32 ack;        size_t datasize;	spin_lock_irqsave(&d->lock, flags);	if (d->fifo_first==NULL) {#if 0		ohci1394_stop_context(ohci, d->ctrlClear, 			     "Packet sent ack received but queue is empty");#endif		spin_unlock_irqrestore(&d->lock, flags);		return;	}	while (d->fifo_first) {		packet = d->fifo_first;                datasize = d->fifo_first->data_size;		if (datasize)			ack = d->prg_cpu[d->sent_ind]->end.status>>16;		else 			ack = d->prg_cpu[d->sent_ind]->begin.status>>16;		if (ack==0) 			/* this packet hasn't been sent yet*/			break;#ifdef OHCI1394_DEBUG		if (datasize)			DBGMSG(ohci->id,			       "Packet sent to node %d tcode=0x%X tLabel="			       "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d", 			       (d->prg_cpu[d->sent_ind]->data[1]>>16)&0x3f,			       (d->prg_cpu[d->sent_ind]->data[0]>>4)&0xf,			       (d->prg_cpu[d->sent_ind]->data[0]>>10)&0x3f,			       ack&0x1f, (ack>>5)&0x3, 			       d->prg_cpu[d->sent_ind]->data[3]>>16,			       d->ctx);		else 			DBGMSG(ohci->id,			       "Packet sent to node %d tcode=0x%X tLabel="			       "0x%02X ack=0x%X spd=%d data=0x%08X ctx=%d", 			       (d->prg_cpu[d->sent_ind]->data[1]>>16)&0x3f,			       (d->prg_cpu[d->sent_ind]->data[0]>>4)&0xf,			       (d->prg_cpu[d->sent_ind]->data[0]>>10)&0x3f,			       ack&0x1f, (ack>>5)&0x3, 			       d->prg_cpu[d->sent_ind]->data[3],			       d->ctx);#endif		                nextpacket = packet->xnext;		hpsb_packet_sent(ohci->host, packet, ack&0xf);		if (datasize)			pci_unmap_single(ohci->dev, 					 d->prg_cpu[d->sent_ind]->end.address,					 datasize, PCI_DMA_TODEVICE);		d->sent_ind = (d->sent_ind+1)%d->num_desc;		d->free_prgs++;		d->fifo_first = nextpacket;	}	if (d->fifo_first==NULL) d->fifo_last=NULL;	dma_trm_flush(ohci, d);	spin_unlock_irqrestore(&d->lock, flags);}static int free_dma_rcv_ctx(struct dma_rcv_ctx **d){	int i;	struct ti_ohci *ohci;	if (*d==NULL) return -1;	ohci = (struct ti_ohci *)(*d)->ohci;	DBGMSG(ohci->id, "Freeing dma_rcv_ctx %d",(*d)->ctx);		ohci1394_stop_context(ohci, (*d)->ctrlClear, NULL);	if ((*d)->buf_cpu) {		for (i=0; i<(*d)->num_desc; i++)			if ((*d)->buf_cpu[i] && (*d)->buf_bus[i]) 				pci_free_consistent(					ohci->dev, (*d)->buf_size, 					(*d)->buf_cpu[i], (*d)->buf_bus[i]);		kfree((*d)->buf_cpu);		kfree((*d)->buf_bus);	}	if ((*d)->prg_cpu) {		for (i=0; i<(*d)->num_desc; i++) 			if ((*d)->prg_cpu[i] && (*d)->prg_bus[i])				pci_free_consistent(					ohci->dev, sizeof(struct dma_cmd), 					(*d)->prg_cpu[i], (*d)->prg_bus[i]);		kfree((*d)->prg_cpu);		kfree((*d)->prg_bus);	}	if ((*d)->spb) kfree((*d)->spb);		kfree(*d);	*d = NULL;	return 0;}static struct dma_rcv_ctx *alloc_dma_rcv_ctx(struct ti_ohci *ohci, int ctx, int num_desc,		  int buf_size, int split_buf_size, 		  int ctrlSet, int ctrlClear, int cmdPtr){	struct dma_rcv_ctx *d=NULL;	int i;	d = (struct dma_rcv_ctx *)kmalloc(sizeof(struct dma_rcv_ctx), 					  GFP_KERNEL);	if (d==NULL) {		PRINT(KERN_ERR, ohci->id, "failed to allocate dma_rcv_ctx");		return NULL;	}	d->ohci = (void *)ohci;	d->ctx = ctx;	d->num_desc = num_desc;	d->buf_size = buf_size;	d->split_buf_size = split_buf_size;	d->ctrlSet = ctrlSet;	d->ctrlClear = ctrlClear;	d->cmdPtr = cmdPtr;	d->buf_cpu = NULL;	d->buf_bus = NULL;	d->prg_cpu = NULL;	d->prg_bus = NULL;	d->spb = NULL;	d->buf_cpu = kmalloc(d->num_desc * sizeof(quadlet_t*), GFP_KERNEL);	d->buf_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL);	if (d->buf_cpu == NULL || d->buf_bus == NULL) {		PRINT(KERN_ERR, ohci->id, "failed to allocate dma buffer");		free_dma_rcv_ctx(&d);		return NULL;	}	memset(d->buf_cpu, 0, d->num_desc * sizeof(quadlet_t*));	memset(d->buf_bus, 0, d->num_desc * sizeof(dma_addr_t));	d->prg_cpu = kmalloc(d->num_desc * sizeof(struct dma_cmd*), 			     GFP_KERNEL);	d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL);	if (d->prg_cpu == NULL || d->prg_bus == NULL) {		PRINT(KERN_ERR, ohci->id, "failed to allocate dma prg");		free_dma_rcv_ctx(&d);		return NULL;	}	memset(d->prg_cpu, 0, d->num_desc * sizeof(struct dma_cmd*));	memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));	d->spb = kmalloc(d->split_buf_size, GFP_KERNEL);	if (d->spb == NULL) {		PRINT(KERN_ERR, ohci->id, "failed to allocate split buffer");		free_dma_rcv_ctx(&d);		return NULL;	}	for (i=0; i<d->num_desc; i++) {                d->buf_cpu[i] = pci_alloc_consistent(ohci->dev, 						     d->buf_size,						     d->buf_bus+i);		                if (d->buf_cpu[i] != NULL) {			memset(d->buf_cpu[i], 0, d->buf_size);		} else {			PRINT(KERN_ERR, ohci->id, 			      "failed to allocate dma buffer");			free_dma_rcv_ctx(&d);			return NULL;		}		                d->prg_cpu[i] = pci_alloc_consistent(ohci->dev, 						     sizeof(struct dma_cmd),						     d->prg_bus+i);                if (d->prg_cpu[i] != NULL) {                        memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd));		} else {			PRINT(KERN_ERR, ohci->id, 			      "failed to allocate dma prg");			free_dma_rcv_ctx(&d);			return NULL;		}	}        spin_lock_init(&d->lock);        /* initialize bottom handler */        d->task.sync = 0;        INIT_LIST_HEAD(&d->task.list);        d->task.routine = dma_rcv_bh;        d->task.data = (void*)d;	return d;}static int free_dma_trm_ctx(struct dma_trm_ctx **d){	struct ti_ohci *ohci;	int i;	if (*d==NULL) return -1;	ohci = (struct ti_ohci *)(*d)->ohci;	DBGMSG(ohci->id, "Freeing dma_trm_ctx %d",(*d)->ctx);	ohci1394_stop_context(ohci, (*d)->ctrlClear, NULL);	if ((*d)->prg_cpu) {		for (i=0; i<(*d)->num_desc; i++) 			if ((*d)->prg_cpu[i] && (*d)->prg_bus[i])				pci_free_consistent(					ohci->dev, sizeof(struct at_dma_prg), 					(*d)->prg_cpu[i], (*d)->prg_bus[i]);		kfree((*d)->prg_cpu);		kfree((*d)->prg_bus);	}	kfree(*d);	*d = NULL;	return 0;}static struct dma_trm_ctx *alloc_dma_trm_ctx(struct ti_ohci *ohci, int ctx, int num_desc,		  int ctrlSet, int ctrlClear, int cmdPtr){	struct dma_trm_ctx *d=NULL;	int i;	d = (struct dma_trm_ctx *)kmalloc(sizeof(struct dma_trm_ctx), 					  GFP_KERNEL);	if (d==NULL) {		PRINT(KERN_ERR, ohci->id, "failed to allocate dma_trm_ctx");		return NULL;	}	d->ohci = (void *)ohci;	d->ctx = ctx;	d->num_desc = num_desc;	d->ctrlSet = ctrlSet;	d->ctrlClear = ctrlClear;	d->cmdPtr = cmdPtr;	d->prg_cpu = NULL;	d->prg_bus = NULL;	d->prg_cpu = kmalloc(d->num_desc * sizeof(struct at_dma_prg*), 			     GFP_KERNEL);	d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL);	if (d->prg_cpu == NULL || d->prg_bus == NULL) {		PRINT(KERN_ERR, ohci->id, "failed to allocate at dma prg");		free_dma_trm_ctx(&d);		return NULL;	}	memset(d->prg_cpu, 0, d->num_desc * sizeof(struct at_dma_prg*));	memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));	for (i=0; i<d->num_desc; i++) {                d->prg_cpu[i] = pci_alloc_consistent(ohci->dev, 						     sizeof(struct at_dma_prg),						     d->prg_bus+i);                if (d->prg_cpu[i] != NULL) {                        memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg));		} else {			PRINT(KERN_ERR, ohci->id, 			      "failed to allocate at dma prg");			free_dma_trm_ctx(&d);			return NULL;		}	}        spin_lock_init(&d->lock);        /* initialize bottom handler */        d->task.routine = dma_trm_bh;        d->task.data = (void*)d;	return d;}static u32 ohci_crc16(unsigned *data, int length){        int check=0, i;        int shift, sum, next=0;        for (i = length; i; i--) {                for (next = check, shift = 28; shift >= 0; shift -= 4 ) {                        sum = ((next >> 12) ^ (*data >> shift)) & 0xf;                        next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);                }                check = next & 0xffff;                data++;        }        return check;}static void ohci_init_config_rom(struct ti_ohci *ohci){	int i;	ohci_csr_rom[3] = reg_read(ohci, OHCI1394_GUIDHi);	ohci_csr_rom[4] = reg_read(ohci, OHCI1394_GUIDLo);		ohci_csr_rom[0] = 0x04040000 | ohci_crc16(ohci_csr_rom+1, 4);	for (i=0;i<sizeof(ohci_csr_rom)/4;i++)		ohci->csr_config_rom_cpu[i] = cpu_to_be32(ohci_csr_rom[i]);}static int add_card(struct pci_dev *dev){	struct ti_ohci *ohci;	/* shortcut to currently handled device */	if (num_of_cards == MAX_OHCI1394_CARDS) {		PRINT_G(KERN_WARNING, "cannot handle more than %d cards.  "			"Adjust MAX_OHCI1394_CARDS in ti_ohci1394.h.",			MAX_OHCI1394_CARDS);		return 1;	}        if (pci_enable_device(dev)) {                PRINT_G(KERN_NOTICE, "failed to enable OHCI hardware %d",                        num_of_cards);                return 1;        }        pci_set_master(dev);	ohci = &cards[num_of_cards++];	ohci->id = num_of_cards-1;	ohci->dev = dev;		ohci->state = 0;	/* csr_config rom allocation */	ohci->csr_config_rom_cpu = 		pci_alloc_consistent(ohci->dev, sizeof(ohci_csr_rom), 				     &ohci->csr_config_rom_bus);	if (ohci->csr_config_rom_cpu == NULL) {		FAIL("failed to allocate buffer config rom");	}	/* 	 * self-id dma buffer allocation	 * FIXME: some early chips may need 8KB alignment for the 	 * selfid buffer... if you have problems a temporary fic	 * is to allocate 8192 bytes instead of 2048	 */	ohci->selfid_buf_cpu = 		pci_alloc_consistent(ohci->dev, 8192, &ohci->selfid_buf_bus);	if (ohci->selfid_buf_cpu == NULL) {		FAIL("failed to allocate DMA buffer for self-id packets");	}	if ((unsigned long)ohci->selfid_buf_cpu & 0x1fff)		PRINT(KERN_INFO, ohci->id, "Selfid buffer %p not aligned on "		      "8Kb boundary... may cause pb on some CXD3222 chip", 		      ohci->selfid_buf_cpu);  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)	ohci->registers = ioremap_nocache(dev->base_address[0],					  OHCI1394_REGISTER_SIZE);#else	ohci->registers = ioremap_nocache(dev->resource[0].start,					  OHCI1394_REGISTER_SIZE);#endif	if (ohci->registers == NULL) {		FAIL("failed to remap registers - card not accessible");	}	PRINT(KERN_INFO, ohci->id, "remapped memory spaces reg 0x%p",	      ohci->registers);	ohci->ar_req_context = 		alloc_dma_rcv_ctx(ohci, 0, AR_REQ_NUM_DESC,				  AR_REQ_BUF_SIZE, AR_REQ_SPLIT_BUF_SIZE,				  OHCI1394_AsReqRcvContextControlSet,				  OHCI1394_AsReqRcvContextControlClear,				  OHCI1394_AsReqRcvCommandPtr);	if (ohci->ar_req_context == NULL) {		FAIL("failed to allocate AR Req context");	}	ohci->ar_resp_context = 		alloc_dma_rcv_ctx(ohci, 1, AR_RESP_NUM_DESC,				  AR_RESP_BUF_SIZE, AR_RESP_SPLIT_BUF_SIZE,				  OHCI1394_AsRspRcvContextControlSet,				  OHCI1394_AsRspRcvContextControlClear,				  OHCI1394_AsRspRcvCommandPtr);		if (ohci->ar_resp_context == NULL) {		FAIL("failed to allocate AR Resp context");	}	ohci->at_req_context = 		alloc_dma_trm_ctx(ohci, 0, AT_REQ_NUM_DESC,				  OHCI1394_AsReqTrContextControlSet,				  OHCI1394_AsReqTrContextControlClear,				  OHCI1394_AsReqTrCommandPtr);		if (ohci->at_req_context == NULL) {		FAIL("failed to allocate AT Req context");	}	ohci->at_resp_context = 		alloc_dma_trm_ctx(ohci, 1, AT_RESP_NUM_DESC,				  OHCI1394_AsRspTrContextControlSet,				  OHCI1394_AsRspTrContextControlClear,				  OHCI1394_AsRspTrCommandPtr);		if (ohci->at_resp_context == NULL) {		FAIL("failed to allocate AT Resp context");

⌨️ 快捷键说明

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