raw1394.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,567 行 · 第 1/5 页

C
1,567
字号
		if (req->req.length == 4)			req->data = &packet->header[3];		else			req->data = packet->data;                break;	case RAW1394_REQ_ASYNC_WRITE:		DBGMSG("write_request called");		packet = hpsb_make_writepacket(fi->host, node, addr, NULL,					       req->req.length);		if (!packet)			return -ENOMEM;		if (req->req.length == 4) {			if (copy_from_user(&packet->header[3], int2ptr(req->req.sendb),					req->req.length))				req->req.error = RAW1394_ERROR_MEMFAULT;		} else {			if (copy_from_user(packet->data, int2ptr(req->req.sendb),					req->req.length))				req->req.error = RAW1394_ERROR_MEMFAULT;		}		req->req.length = 0;	    break;	case RAW1394_REQ_ASYNC_STREAM:		DBGMSG("stream_request called");		packet = hpsb_make_streampacket(fi->host, NULL, req->req.length, node & 0x3f/*channel*/,                                        (req->req.misc >> 16) & 0x3, req->req.misc & 0xf);		if (!packet)			return -ENOMEM;		if (copy_from_user(packet->data, int2ptr(req->req.sendb),		                   req->req.length))			req->req.error = RAW1394_ERROR_MEMFAULT;		req->req.length = 0;		break;        case RAW1394_REQ_LOCK:                DBGMSG("lock_request called");                if ((req->req.misc == EXTCODE_FETCH_ADD)                    || (req->req.misc == EXTCODE_LITTLE_ADD)) {                        if (req->req.length != 4) {                                req->req.error = RAW1394_ERROR_INVALID_ARG;                                break;                        }                } else {                        if (req->req.length != 8) {                                req->req.error = RAW1394_ERROR_INVALID_ARG;                                break;                        }                }                packet = hpsb_make_lockpacket(fi->host, node, addr,                                              req->req.misc, NULL, 0);                if (!packet) return -ENOMEM;                if (copy_from_user(packet->data, int2ptr(req->req.sendb),                                   req->req.length)) {                        req->req.error = RAW1394_ERROR_MEMFAULT;                        break;                }                req->data = packet->data;                req->req.length = 4;                break;        case RAW1394_REQ_LOCK64:                DBGMSG("lock64_request called");                if ((req->req.misc == EXTCODE_FETCH_ADD)                    || (req->req.misc == EXTCODE_LITTLE_ADD)) {                        if (req->req.length != 8) {                                req->req.error = RAW1394_ERROR_INVALID_ARG;                                break;                        }                } else {                        if (req->req.length != 16) {                                req->req.error = RAW1394_ERROR_INVALID_ARG;                                break;                        }                }                packet = hpsb_make_lock64packet(fi->host, node, addr,                                                req->req.misc, NULL, 0);                if (!packet) return -ENOMEM;                if (copy_from_user(packet->data, int2ptr(req->req.sendb),                                   req->req.length)) {                        req->req.error = RAW1394_ERROR_MEMFAULT;                        break;                }                req->data = packet->data;                req->req.length = 8;                break;        default:                req->req.error = RAW1394_ERROR_STATE_ORDER;        }        req->packet = packet;        if (req->req.error) {                req->req.length = 0;                queue_complete_req(req);                return sizeof(struct raw1394_request);        }	hpsb_set_packet_complete_task(packet, (void(*)(void*))queue_complete_cb, req);        spin_lock_irq(&fi->reqlists_lock);        list_add_tail(&req->list, &fi->req_pending);        spin_unlock_irq(&fi->reqlists_lock);	packet->generation = req->req.generation;        if (hpsb_send_packet(packet) < 0) {                req->req.error = RAW1394_ERROR_SEND_ERROR;                req->req.length = 0;                hpsb_free_tlabel(packet);                queue_complete_req(req);        }        return sizeof(struct raw1394_request);}static int handle_iso_send(struct file_info *fi, struct pending_request *req,                           int channel){        struct hpsb_packet *packet;	packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f,				     (req->req.misc >> 16) & 0x3, req->req.misc & 0xf);	if (!packet)		return -ENOMEM;        packet->speed_code = req->req.address & 0x3;	req->packet = packet;        if (copy_from_user(packet->data, int2ptr(req->req.sendb),                           req->req.length)) {                req->req.error = RAW1394_ERROR_MEMFAULT;                req->req.length = 0;                queue_complete_req(req);                return sizeof(struct raw1394_request);        }        req->req.length = 0;	hpsb_set_packet_complete_task(packet, (void (*)(void*))queue_complete_req, req);        spin_lock_irq(&fi->reqlists_lock);        list_add_tail(&req->list, &fi->req_pending);        spin_unlock_irq(&fi->reqlists_lock);	/* Update the generation of the packet just before sending. */	packet->generation = req->req.generation;        if (hpsb_send_packet(packet) < 0) {                req->req.error = RAW1394_ERROR_SEND_ERROR;                queue_complete_req(req);        }        return sizeof(struct raw1394_request);}static int handle_async_send(struct file_info *fi, struct pending_request *req){        struct hpsb_packet *packet;        int header_length = req->req.misc & 0xffff;        int expect_response = req->req.misc >> 16;        if ((header_length > req->req.length) ||            (header_length  < 12)) {                req->req.error = RAW1394_ERROR_INVALID_ARG;                req->req.length = 0;                queue_complete_req(req);                return sizeof(struct raw1394_request);        }        packet = hpsb_alloc_packet(req->req.length-header_length);        req->packet = packet;        if (!packet) return -ENOMEM;        if (copy_from_user(packet->header, int2ptr(req->req.sendb),                           header_length)) {                req->req.error = RAW1394_ERROR_MEMFAULT;                req->req.length = 0;                queue_complete_req(req);                return sizeof(struct raw1394_request);        }        if (copy_from_user(packet->data, int2ptr(req->req.sendb) + header_length,                           packet->data_size)) {                req->req.error = RAW1394_ERROR_MEMFAULT;                req->req.length = 0;                queue_complete_req(req);                return sizeof(struct raw1394_request);        }        packet->type = hpsb_async;        packet->node_id = packet->header[0] >> 16;        packet->tcode = (packet->header[0] >> 4) & 0xf;        packet->tlabel = (packet->header[0] >> 10) &0x3f;        packet->host = fi->host;        packet->expect_response = expect_response;        packet->header_size=header_length;        packet->data_size=req->req.length-header_length;        req->req.length = 0;        hpsb_set_packet_complete_task(packet, (void(*)(void*))queue_complete_cb, req);        spin_lock_irq(&fi->reqlists_lock);        list_add_tail(&req->list, &fi->req_pending);        spin_unlock_irq(&fi->reqlists_lock);        /* Update the generation of the packet just before sending. */        packet->generation = req->req.generation;        if (hpsb_send_packet(packet) < 0) {                req->req.error = RAW1394_ERROR_SEND_ERROR;                queue_complete_req(req);        }        return sizeof(struct raw1394_request);}static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,		     u64 addr, size_t length, u16 flags){        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;        struct arm_request_response *arm_req_resp = NULL;        DBGMSG("arm_read  called by node: %X"              "addr: %4.4x %8.8x length: %Zu", nodeid,              (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),              length);        spin_lock(&host_info_lock);        hi = find_host_info(host); /* search address-entry */        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+length))) {                                        found = 1;                                        break;                                }                                entry = entry->next;                        }                        if (found) {                                break;                        }                }        }        rcode = -1;        if (!found) {                printk(KERN_ERR "raw1394: arm_read FAILED addr_entry not found"                " -> rcode_address_error\n");                spin_unlock(&host_info_lock);                return (RCODE_ADDRESS_ERROR);        } else {                DBGMSG("arm_read addr_entry FOUND");        }        if (arm_addr->rec_length < length) {                DBGMSG("arm_read blocklength too big -> rcode_data_error");                rcode = RCODE_DATA_ERROR; /* hardware error, data is unavailable */        }        if (rcode == -1) {                if (arm_addr->access_rights & ARM_READ) {                        if (!(arm_addr->client_transactions & ARM_READ)) {                                memcpy(buffer,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)),                                       length);                                DBGMSG("arm_read -> (rcode_complete)");                                rcode = RCODE_COMPLETE;                        }                } else {                        rcode = RCODE_TYPE_ERROR; /* function not allowed */                        DBGMSG("arm_read -> rcode_type_error (access denied)");                }        }        if (arm_addr->notification_options & ARM_READ) {                DBGMSG("arm_read -> entering notification-section");                req = __alloc_pending_request(SLAB_ATOMIC);                if (!req) {                        DBGMSG("arm_read -> rcode_conflict_error");                        spin_unlock(&host_info_lock);                        return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected.                                                        The request may be retried */                }                if (rcode == RCODE_COMPLETE) {                        size =  sizeof(struct arm_request)+sizeof(struct arm_response) +                                length * sizeof(byte_t) +                                sizeof (struct arm_request_response);                } else {                        size =  sizeof(struct arm_request)+sizeof(struct arm_response) +                                sizeof (struct arm_request_response);                }                req->data = kmalloc(size, SLAB_ATOMIC);                if (!(req->data)) {                        free_pending_request(req);                        DBGMSG("arm_read -> rcode_conflict_error");                        spin_unlock(&host_info_lock);

⌨️ 快捷键说明

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