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

📄 raw1394.c

📁 ieee1394驱动,不多说了!直接可以在linux2.6内核中使用
💻 C
📖 第 1 页 / 共 5 页
字号:
						new = data;					}					break;				default:					rcode = RCODE_TYPE_ERROR;	/* function not allowed */					printk(KERN_ERR					       "raw1394: arm_lock FAILED "					       "ext_tcode not allowed -> rcode_type_error\n");					break;				}	/*switch */				if (rcode == -1) {					DBGMSG("arm_lock -> (rcode_complete)");					rcode = RCODE_COMPLETE;					memcpy(store, &old, sizeof(*store));					memcpy((arm_addr->addr_space_buffer) +					       (addr - (arm_addr->start)),					       &new, sizeof(*store));				}			}		} else {			rcode = RCODE_TYPE_ERROR;	/* function not allowed */			DBGMSG("arm_lock -> rcode_type_error (access denied)");		}	}	if (arm_addr->notification_options & ARM_LOCK) {		byte_t *buf1, *buf2;		DBGMSG("arm_lock -> entering notification-section");		req = __alloc_pending_request(GFP_ATOMIC);		if (!req) {			DBGMSG("arm_lock -> rcode_conflict_error");			spin_unlock_irqrestore(&host_info_lock, irqflags);			return (RCODE_CONFLICT_ERROR);	/* A resource conflict was detected.							   The request may be retried */		}		size = sizeof(struct arm_request) + sizeof(struct arm_response) + 3 * sizeof(*store) + sizeof(struct arm_request_response);	/* maximum */		req->data = kmalloc(size, GFP_ATOMIC);		if (!(req->data)) {			free_pending_request(req);			DBGMSG("arm_lock -> rcode_conflict_error");			spin_unlock_irqrestore(&host_info_lock, irqflags);			return (RCODE_CONFLICT_ERROR);	/* A resource conflict was detected.							   The request may be retried */		}		req->free_data = 1;		arm_req_resp = (struct arm_request_response *)(req->data);		arm_req = (struct arm_request *)((byte_t *) (req->data) +						 (sizeof						  (struct						   arm_request_response)));		arm_resp =		    (struct arm_response *)((byte_t *) (arm_req) +					    (sizeof(struct arm_request)));		buf1 = (byte_t *) arm_resp + sizeof(struct arm_response);		buf2 = buf1 + 2 * sizeof(*store);		if ((ext_tcode == EXTCODE_FETCH_ADD) ||		    (ext_tcode == EXTCODE_LITTLE_ADD)) {			arm_req->buffer_length = sizeof(*store);			memcpy(buf1, &data, sizeof(*store));		} else {			arm_req->buffer_length = 2 * sizeof(*store);			memcpy(buf1, &arg, sizeof(*store));			memcpy(buf1 + sizeof(*store), &data, sizeof(*store));		}		if (rcode == RCODE_COMPLETE) {			arm_resp->buffer_length = sizeof(*store);			memcpy(buf2, &old, sizeof(*store));		} else {			arm_resp->buffer_length = 0;		}		req->file_info = fi;		req->req.type = RAW1394_REQ_ARM;		req->req.generation = get_hpsb_generation(host);		req->req.misc = ((((sizeof(*store)) << 16) & (0xFFFF0000)) |				 (ARM_LOCK & 0xFF));		req->req.tag = arm_addr->arm_tag;		req->req.recvb = arm_addr->recvb;		req->req.length = size;		arm_req->generation = req->req.generation;		arm_req->extended_transaction_code = ext_tcode;		arm_req->destination_offset = addr;		arm_req->source_nodeid = nodeid;		arm_req->destination_nodeid = host->node_id;		arm_req->tlabel = (flags >> 10) & 0x3f;		arm_req->tcode = (flags >> 4) & 0x0f;		arm_resp->response_code = rcode;		arm_req_resp->request = int2ptr((arm_addr->recvb) +						sizeof(struct						       arm_request_response));		arm_req_resp->response =		    int2ptr((arm_addr->recvb) +			    sizeof(struct arm_request_response) +			    sizeof(struct arm_request));		arm_req->buffer =		    int2ptr((arm_addr->recvb) +			    sizeof(struct arm_request_response) +			    sizeof(struct arm_request) +			    sizeof(struct arm_response));		arm_resp->buffer =		    int2ptr((arm_addr->recvb) +			    sizeof(struct arm_request_response) +			    sizeof(struct arm_request) +			    sizeof(struct arm_response) + 2 * sizeof(*store));		queue_complete_req(req);	}	spin_unlock_irqrestore(&host_info_lock, irqflags);	return (rcode);}static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,		      u64 addr, octlet_t data, octlet_t arg, int ext_tcode,		      u16 flags){	unsigned long irqflags;	struct pending_request *req;	struct host_info *hi;	struct file_info *fi = NULL;	struct list_head *entry;	struct arm_addr *arm_addr = NULL;	struct arm_request *arm_req = NULL;	struct arm_response *arm_resp = NULL;	int found = 0, size = 0, rcode = -1;	octlet_t old, new;	struct arm_request_response *arm_req_resp = NULL;	if (((ext_tcode & 0xFF) == EXTCODE_FETCH_ADD) ||	    ((ext_tcode & 0xFF) == EXTCODE_LITTLE_ADD)) {		DBGMSG("arm_lock64 called by node: %X "		       "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X ",		       nodeid, (u16) ((addr >> 32) & 0xFFFF),		       (u32) (addr & 0xFFFFFFFF),		       ext_tcode & 0xFF,		       (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF),		       (u32) (be64_to_cpu(data) & 0xFFFFFFFF));	} else {		DBGMSG("arm_lock64 called by node: %X "		       "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X arg: "		       "%8.8X %8.8X ",		       nodeid, (u16) ((addr >> 32) & 0xFFFF),		       (u32) (addr & 0xFFFFFFFF),		       ext_tcode & 0xFF,		       (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF),		       (u32) (be64_to_cpu(data) & 0xFFFFFFFF),		       (u32) ((be64_to_cpu(arg) >> 32) & 0xFFFFFFFF),		       (u32) (be64_to_cpu(arg) & 0xFFFFFFFF));	}	spin_lock_irqsave(&host_info_lock, irqflags);	hi = find_host_info(host);	/* search addressentry in file_info's for host */	if (hi != NULL) {		list_for_each_entry(fi, &hi->file_info_list, list) {			entry = fi->addr_list.next;			while (entry != &(fi->addr_list)) {				arm_addr =				    list_entry(entry, struct arm_addr,					       addr_list);				if (((arm_addr->start) <= (addr))				    && ((arm_addr->end) >=					(addr + sizeof(*store)))) {					found = 1;					break;				}				entry = entry->next;			}			if (found) {				break;			}		}	}	rcode = -1;	if (!found) {		printk(KERN_ERR		       "raw1394: arm_lock64 FAILED addr_entry not found"		       " -> rcode_address_error\n");		spin_unlock_irqrestore(&host_info_lock, irqflags);		return (RCODE_ADDRESS_ERROR);	} else {		DBGMSG("arm_lock64 addr_entry FOUND");	}	if (rcode == -1) {		if (arm_addr->access_rights & ARM_LOCK) {			if (!(arm_addr->client_transactions & ARM_LOCK)) {				memcpy(&old,				       (arm_addr->addr_space_buffer) + (addr -									(arm_addr->									 start)),				       sizeof(old));				switch (ext_tcode) {				case (EXTCODE_MASK_SWAP):					new = data | (old & ~arg);					break;				case (EXTCODE_COMPARE_SWAP):					if (old == arg) {						new = data;					} else {						new = old;					}					break;				case (EXTCODE_FETCH_ADD):					new =					    cpu_to_be64(be64_to_cpu(data) +							be64_to_cpu(old));					break;				case (EXTCODE_LITTLE_ADD):					new =					    cpu_to_le64(le64_to_cpu(data) +							le64_to_cpu(old));					break;				case (EXTCODE_BOUNDED_ADD):					if (old != arg) {						new =						    cpu_to_be64(be64_to_cpu								(data) +								be64_to_cpu								(old));					} else {						new = old;					}					break;				case (EXTCODE_WRAP_ADD):					if (old != arg) {						new =						    cpu_to_be64(be64_to_cpu								(data) +								be64_to_cpu								(old));					} else {						new = data;					}					break;				default:					printk(KERN_ERR					       "raw1394: arm_lock64 FAILED "					       "ext_tcode not allowed -> rcode_type_error\n");					rcode = RCODE_TYPE_ERROR;	/* function not allowed */					break;				}	/*switch */				if (rcode == -1) {					DBGMSG					    ("arm_lock64 -> (rcode_complete)");					rcode = RCODE_COMPLETE;					memcpy(store, &old, sizeof(*store));					memcpy((arm_addr->addr_space_buffer) +					       (addr - (arm_addr->start)),					       &new, sizeof(*store));				}			}		} else {			rcode = RCODE_TYPE_ERROR;	/* function not allowed */			DBGMSG			    ("arm_lock64 -> rcode_type_error (access denied)");		}	}	if (arm_addr->notification_options & ARM_LOCK) {		byte_t *buf1, *buf2;		DBGMSG("arm_lock64 -> entering notification-section");		req = __alloc_pending_request(GFP_ATOMIC);		if (!req) {			spin_unlock_irqrestore(&host_info_lock, irqflags);			DBGMSG("arm_lock64 -> rcode_conflict_error");			return (RCODE_CONFLICT_ERROR);	/* A resource conflict was detected.							   The request may be retried */		}		size = sizeof(struct arm_request) + sizeof(struct arm_response) + 3 * sizeof(*store) + sizeof(struct arm_request_response);	/* maximum */		req->data = kmalloc(size, GFP_ATOMIC);		if (!(req->data)) {			free_pending_request(req);			spin_unlock_irqrestore(&host_info_lock, irqflags);			DBGMSG("arm_lock64 -> rcode_conflict_error");			return (RCODE_CONFLICT_ERROR);	/* A resource conflict was detected.							   The request may be retried */		}		req->free_data = 1;		arm_req_resp = (struct arm_request_response *)(req->data);		arm_req = (struct arm_request *)((byte_t *) (req->data) +						 (sizeof						  (struct						   arm_request_response)));		arm_resp =		    (struct arm_response *)((byte_t *) (arm_req) +					    (sizeof(struct arm_request)));		buf1 = (byte_t *) arm_resp + sizeof(struct arm_response);		buf2 = buf1 + 2 * sizeof(*store);		if ((ext_tcode == EXTCODE_FETCH_ADD) ||		    (ext_tcode == EXTCODE_LITTLE_ADD)) {			arm_req->buffer_length = sizeof(*store);			memcpy(buf1, &data, sizeof(*store));		} else {			arm_req->buffer_length = 2 * sizeof(*store);			memcpy(buf1, &arg, sizeof(*store));			memcpy(buf1 + sizeof(*store), &data, sizeof(*store));		}		if (rcode == RCODE_COMPLETE) {			arm_resp->buffer_length = sizeof(*store);			memcpy(buf2, &old, sizeof(*store));		} else {			arm_resp->buffer_length = 0;		}		req->file_info = fi;		req->req.type = RAW1394_REQ_ARM;		req->req.generation = get_hpsb_generation(host);		req->req.misc = ((((sizeof(*store)) << 16) & (0xFFFF0000)) |				 (ARM_LOCK & 0xFF));		req->req.tag = arm_addr->arm_tag;		req->req.recvb = arm_addr->recvb;		req->req.length = size;		arm_req->generation = req->req.generation;		arm_req->extended_transaction_code = ext_tcode;		arm_req->destination_offset = addr;		arm_req->source_nodeid = nodeid;		arm_req->destination_nodeid = host->node_id;		arm_req->tlabel = (flags >> 10) & 0x3f;		arm_req->tcode = (flags >> 4) & 0x0f;		arm_resp->response_code = rcode;		arm_req_resp->request = int2ptr((arm_addr->recvb) +						sizeof(struct						       arm_request_response));		arm_req_resp->response =		    int2ptr((arm_addr->recvb) +			    sizeof(struct arm_request_response) +			    sizeof(struct arm_request));		arm_req->buffer =		    int2ptr((arm_addr->recvb) +			    sizeof(struct arm_request_response) +			    sizeof(struct arm_request) +			    sizeof(struct arm_response));		arm_resp->buffer =		    int2ptr((arm_addr->recvb) +			    sizeof(struct arm_request_response) +			    sizeof(struct arm_request) +			    sizeof(struct arm_response) + 2 * sizeof(*store));		queue_complete_req(req);	}	spin_unlock_irqrestore(&host_info_lock, irqflags);	return (rcode);}static int arm_register(struct file_info *fi, struct pending_request *req){	int retval;	struct arm_addr *addr;	struct host_info *hi;	struct file_info *fi_hlp = NULL;	struct list_head *entry;	struct arm_addr *arm_addr = NULL;	int same_host, another_host;	unsigned long flags;	DBGMSG("arm_register called "	       "addr(Offset): %8.8x %8.8x length: %u "	       "rights: %2.2X notify: %2.2X "	       "max_blk_len: %4.4X",	       (u32) ((req->req.address >> 32) & 0xFFFF),	       (u32) (req->req.address & 0xFFFFFFFF),	       req->req.length, ((req->req.misc >> 8) & 0xFF),	       (req->req.misc & 0xFF), ((req->req.misc >> 16) & 0xFFFF));	/* check addressrange */	if ((((req->req.address) & ~(0xFFFFFFFFFFFFULL)) != 0) ||	    (((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFFULL)) !=	     0)) {		req->req.length = 0;		return (-EINVAL);	}	/* addr-list-entry for fileinfo */	addr = kmalloc(sizeof(*addr), GFP_KERNEL);	if (!addr) {		req->req.length = 0;		return (-ENOMEM);	}	/* allocation of addr_space_buffer */	addr->addr_space_buffer = vmalloc(req->req.length);	if (!(addr->addr_space_buffer)) {		kfree(addr);		req->req.length = 0;		return (-ENOMEM);	}	/* initialization of addr_space_buffer */	if ((req->req.sendb) == (unsigned long)NULL) {		/* init: set 0 */		memset(addr->addr_space_buffer, 0, req->req.length);	} else {		/* init: user -> kernel */		if (copy_from_user		    (addr->addr_space_buffer, int2ptr(req->req.sendb),		     req->req.length)) {			vfree(addr->addr_space_buffer);			kfree(addr);			return (-EFAULT);		}	}	INIT_LIST_HEAD(&addr->addr_list);	addr->arm_tag = req->req.tag;	addr->start = req->req.address;	addr->end = req->req.address + req->req.length;	addr->access_rights = (u8) (req->req.misc & 0x0F);	addr->notification_options = (u8) ((req->req.misc >> 4) & 0x0F);	addr->client_transactions = (u8) ((req->req.misc >> 8) & 0x0F);	addr->access_rights |= addr->client_transactions;	addr->notification_options |= addr->client_transactions;	addr->recvb = req->req.recvb;	addr->rec_length = (u16) ((req->req.misc >> 16) & 0xFFFF);	spin_lock_irqsave(&host_info_lock, flags);	hi = find_host_info(fi->host);	same_host = 0;	another_host = 0;	/* same host with address-entry containing same addressrange ? */	list_for_each_entry(fi_hlp, &hi->file_info_list, list) {		entry = fi_hlp->addr_list.next;		while (entry != &(fi_hlp->addr_list)) {			arm_addr =			    list_entry(entry, struct arm_addr, addr_list);			if ((arm_addr->start == addr->start)			    && (arm_addr->end == addr->end)) {				DBGMSG("same host ownes same "				       "addressrange -> EALREADY");				same_host = 1;				break;			}			entry = entry->next;		}		if (same_host) {			break;		}	}	if (same_host) {		/* addressrange occupied by same host */		spin_unlock_irqrestore(&host_info_lock, flags);		vfree(addr->addr_space_buffer);		kfree(addr);		return (-EALREADY);	}	/* another host with valid address-entry containing same addressrange */	list_for_each_entry(hi, &host_info_list, list) {		if (hi->host != fi->host) {			list_for_each_entry(fi_hlp, &hi->file_info_list, list) {				entry = fi_hlp->addr_list.next;				while (entry != &(fi_hlp->addr_list)) {					arm_addr =					    list_entry(entry, struct arm_addr,						       addr_list);					if ((arm_addr->start == addr->start)					    && (arm_addr->end == addr->end)) {						DBGMSG						    ("another host ownes same "						     "addressrange");						another_host = 1;						break;					}					entry = entry->next;				}				if (another_host) {					break;				}			}		}	}	spin_unlock_irqrestore(&host_info_lock, flags);	if (another_host) {		DBGMSG("another hosts entry is valid -> SUCCESS");		if (copy_to_user(int2ptr(req->req.recvb),				 &addr->start, sizeof(u64))) {			printk(KERN_ERR "raw1394: arm_register failed "			       " address-range-entry is invalid -> EFAULT !!!\n");

⌨️ 快捷键说明

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