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

📄 ieee1394_core.c

📁 Armlinux ieee1394接口驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
        }}void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,                            size_t size){        struct hpsb_packet *packet = NULL;        struct list_head *lh;        int tcode_match = 0;        int tlabel;        unsigned long flags;        tlabel = (data[0] >> 10) & 0x3f;        spin_lock_irqsave(&host->pending_pkt_lock, flags);        list_for_each(lh, &host->pending_packets) {                packet = list_entry(lh, struct hpsb_packet, list);                if ((packet->tlabel == tlabel)                    && (packet->node_id == (data[1] >> 16))){                        break;                }        }        if (lh == &host->pending_packets) {                HPSB_DEBUG("unsolicited response packet received - np");                dump_packet("contents:", data, 16);                spin_unlock_irqrestore(&host->pending_pkt_lock, flags);                return;        }        switch (packet->tcode) {        case TCODE_WRITEQ:        case TCODE_WRITEB:                if (tcode == TCODE_WRITE_RESPONSE) tcode_match = 1;                break;        case TCODE_READQ:                if (tcode == TCODE_READQ_RESPONSE) tcode_match = 1;                break;        case TCODE_READB:                if (tcode == TCODE_READB_RESPONSE) tcode_match = 1;                break;        case TCODE_LOCK_REQUEST:                if (tcode == TCODE_LOCK_RESPONSE) tcode_match = 1;                break;        }        if (!tcode_match || (packet->tlabel != tlabel)            || (packet->node_id != (data[1] >> 16))) {                HPSB_INFO("unsolicited response packet received");                dump_packet("contents:", data, 16);                spin_unlock_irqrestore(&host->pending_pkt_lock, flags);                return;        }        list_del(&packet->list);        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);        /* FIXME - update size fields? */        switch (tcode) {        case TCODE_WRITE_RESPONSE:                memcpy(packet->header, data, 12);                break;        case TCODE_READQ_RESPONSE:                memcpy(packet->header, data, 16);                break;        case TCODE_READB_RESPONSE:                memcpy(packet->header, data, 16);                memcpy(packet->data, data + 4, size - 16);                break;        case TCODE_LOCK_RESPONSE:                memcpy(packet->header, data, 16);                memcpy(packet->data, data + 4, (size - 16) > 8 ? 8 : size - 16);                break;        }        packet->state = hpsb_complete;        up(&packet->state_change);        run_task_queue(&packet->complete_tq);}static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,					       quadlet_t *data, size_t dsize){        struct hpsb_packet *p;        dsize += (dsize % 4 ? 4 - (dsize % 4) : 0);        p = alloc_hpsb_packet(dsize);        if (p == NULL) {                /* FIXME - send data_error response */                return NULL;        }        p->type = hpsb_async;        p->state = hpsb_unused;        p->host = host;        p->node_id = data[1] >> 16;        p->tlabel = (data[0] >> 10) & 0x3f;        p->no_waiter = 1;	p->generation = get_hpsb_generation(host);        if (dsize % 4) {                p->data[dsize / 4] = 0;        }        return p;}#define PREP_REPLY_PACKET(length) \                packet = create_reply_packet(host, data, length); \                if (packet == NULL) breakstatic void handle_incoming_packet(struct hpsb_host *host, int tcode,				   quadlet_t *data, size_t size, int write_acked){        struct hpsb_packet *packet;        int length, rcode, extcode;        nodeid_t source = data[1] >> 16;	nodeid_t dest = data[0] >> 16;        u64 addr;        /* big FIXME - no error checking is done for an out of bounds length */        switch (tcode) {        case TCODE_WRITEQ:                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                rcode = highlevel_write(host, source, dest, data+3,					addr, 4);                if (!write_acked                    && ((data[0] >> 16) & NODE_MASK) != NODE_MASK) {                        /* not a broadcast write, reply */                        PREP_REPLY_PACKET(0);                        fill_async_write_resp(packet, rcode);                        send_packet_nocare(packet);                }                break;        case TCODE_WRITEB:                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                rcode = highlevel_write(host, source, dest, data+4,					addr, data[3]>>16);                if (!write_acked                    && ((data[0] >> 16) & NODE_MASK) != NODE_MASK) {                        /* not a broadcast write, reply */                        PREP_REPLY_PACKET(0);                        fill_async_write_resp(packet, rcode);                        send_packet_nocare(packet);                }                break;        case TCODE_READQ:                PREP_REPLY_PACKET(0);                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                rcode = highlevel_read(host, source, data, addr, 4);                fill_async_readquad_resp(packet, rcode, *data);                send_packet_nocare(packet);                break;        case TCODE_READB:                length = data[3] >> 16;                PREP_REPLY_PACKET(length);                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                rcode = highlevel_read(host, source, packet->data, addr,                                       length);                fill_async_readblock_resp(packet, rcode, length);                send_packet_nocare(packet);                break;        case TCODE_LOCK_REQUEST:                length = data[3] >> 16;                extcode = data[3] & 0xffff;                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                PREP_REPLY_PACKET(8);                if ((extcode == 0) || (extcode >= 7)) {                        /* let switch default handle error */                        length = 0;                }                switch (length) {                case 4:                        rcode = highlevel_lock(host, source, packet->data, addr,                                               data[4], 0, extcode);                        fill_async_lock_resp(packet, rcode, extcode, 4);                        break;                case 8:                        if ((extcode != EXTCODE_FETCH_ADD)                             && (extcode != EXTCODE_LITTLE_ADD)) {                                rcode = highlevel_lock(host, source,                                                       packet->data, addr,                                                       data[5], data[4],                                                        extcode);                                fill_async_lock_resp(packet, rcode, extcode, 4);                        } else {                                rcode = highlevel_lock64(host, source,                                             (octlet_t *)packet->data, addr,                                             *(octlet_t *)(data + 4), 0ULL,                                             extcode);                                fill_async_lock_resp(packet, rcode, extcode, 8);                        }                        break;                case 16:                        rcode = highlevel_lock64(host, source,                                                 (octlet_t *)packet->data, addr,                                                 *(octlet_t *)(data + 6),                                                 *(octlet_t *)(data + 4),                                                  extcode);                        fill_async_lock_resp(packet, rcode, extcode, 8);                        break;                default:                        fill_async_lock_resp(packet, RCODE_TYPE_ERROR,                                             extcode, 0);                }                send_packet_nocare(packet);                break;        }}#undef PREP_REPLY_PACKETvoid hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,                          int write_acked){        int tcode;        if (host->in_bus_reset) {                HPSB_INFO("received packet during reset; ignoring");                return;        }#ifdef CONFIG_IEEE1394_VERBOSEDEBUG        dump_packet("received packet:", data, size);#endif        tcode = (data[0] >> 4) & 0xf;        switch (tcode) {        case TCODE_WRITE_RESPONSE:        case TCODE_READQ_RESPONSE:        case TCODE_READB_RESPONSE:        case TCODE_LOCK_RESPONSE:                handle_packet_response(host, tcode, data, size);                break;        case TCODE_WRITEQ:        case TCODE_WRITEB:        case TCODE_READQ:        case TCODE_READB:        case TCODE_LOCK_REQUEST:                handle_incoming_packet(host, tcode, data, size, write_acked);                break;        case TCODE_ISO_DATA:                highlevel_iso_receive(host, data, size);                break;        case TCODE_CYCLE_START:                /* simply ignore this packet if it is passed on */                break;        default:                HPSB_NOTICE("received packet with bogus transaction code %d",                             tcode);                break;        }}void abort_requests(struct hpsb_host *host){        unsigned long flags;        struct hpsb_packet *packet;        struct list_head *lh;        LIST_HEAD(llist);        host->template->devctl(host, CANCEL_REQUESTS, 0);        spin_lock_irqsave(&host->pending_pkt_lock, flags);        list_splice(&host->pending_packets, &llist);        INIT_LIST_HEAD(&host->pending_packets);        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);        list_for_each(lh, &llist) {                packet = list_entry(lh, struct hpsb_packet, list);                packet->state = hpsb_complete;                packet->ack_code = ACKX_ABORTED;                up(&packet->state_change);                run_task_queue(&packet->complete_tq);        }}void abort_timedouts(struct hpsb_host *host){        unsigned long flags;        struct hpsb_packet *packet;        unsigned long expire;        struct list_head *lh, *next;        LIST_HEAD(expiredlist);        spin_lock_irqsave(&host->csr.lock, flags);        expire = (host->csr.split_timeout_hi * 8000                   + (host->csr.split_timeout_lo >> 19))                * HZ / 8000;        /* Avoid shortening of timeout due to rounding errors: */        expire++;        spin_unlock_irqrestore(&host->csr.lock, flags);        spin_lock_irqsave(&host->pending_pkt_lock, flags);	for (lh = host->pending_packets.next; lh != &host->pending_packets; lh = next) {                packet = list_entry(lh, struct hpsb_packet, list);		next = lh->next;                if (time_before(packet->sendtime + expire, jiffies)) {                        list_del(&packet->list);                        list_add(&packet->list, &expiredlist);                }        }        if (!list_empty(&host->pending_packets)) {                queue_task(&host->timeout_tq, &tq_timer);        }        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);        list_for_each(lh, &expiredlist) {                packet = list_entry(lh, struct hpsb_packet, list);                packet->state = hpsb_complete;                packet->ack_code = ACKX_TIMEOUT;                up(&packet->state_change);                run_task_queue(&packet->complete_tq);        }}static int __init ieee1394_init(void){	hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet),					      0, 0, NULL, NULL);	init_hpsb_highlevel();	init_csr();	if (!disable_nodemgr)		init_ieee1394_nodemgr();	else		HPSB_INFO("nodemgr functionality disabled");	return 0;}static void __exit ieee1394_cleanup(void){	if (!disable_nodemgr)		cleanup_ieee1394_nodemgr();	cleanup_csr();	kmem_cache_destroy(hpsb_packet_cache);}module_init(ieee1394_init);module_exit(ieee1394_cleanup);/* Exported symbols */EXPORT_SYMBOL(hpsb_register_lowlevel);EXPORT_SYMBOL(hpsb_unregister_lowlevel);EXPORT_SYMBOL(hpsb_get_host);EXPORT_SYMBOL(hpsb_inc_host_usage);EXPORT_SYMBOL(hpsb_dec_host_usage);EXPORT_SYMBOL(hpsb_speedto_str);EXPORT_SYMBOL(alloc_hpsb_packet);EXPORT_SYMBOL(free_hpsb_packet);EXPORT_SYMBOL(hpsb_send_packet);EXPORT_SYMBOL(hpsb_reset_bus);EXPORT_SYMBOL(hpsb_bus_reset);EXPORT_SYMBOL(hpsb_selfid_received);EXPORT_SYMBOL(hpsb_selfid_complete);EXPORT_SYMBOL(hpsb_packet_sent);EXPORT_SYMBOL(hpsb_packet_received);EXPORT_SYMBOL(get_tlabel);EXPORT_SYMBOL(free_tlabel);EXPORT_SYMBOL(fill_async_readquad);EXPORT_SYMBOL(fill_async_readquad_resp);EXPORT_SYMBOL(fill_async_readblock);EXPORT_SYMBOL(fill_async_readblock_resp);EXPORT_SYMBOL(fill_async_writequad);EXPORT_SYMBOL(fill_async_writeblock);EXPORT_SYMBOL(fill_async_write_resp);EXPORT_SYMBOL(fill_async_lock);EXPORT_SYMBOL(fill_async_lock_resp);EXPORT_SYMBOL(fill_iso_packet);EXPORT_SYMBOL(fill_phy_packet);EXPORT_SYMBOL(hpsb_make_readqpacket);EXPORT_SYMBOL(hpsb_make_readbpacket);EXPORT_SYMBOL(hpsb_make_writeqpacket);EXPORT_SYMBOL(hpsb_make_writebpacket);EXPORT_SYMBOL(hpsb_make_lockpacket);EXPORT_SYMBOL(hpsb_make_phypacket);EXPORT_SYMBOL(hpsb_packet_success);EXPORT_SYMBOL(hpsb_make_packet);EXPORT_SYMBOL(hpsb_read);EXPORT_SYMBOL(hpsb_write);EXPORT_SYMBOL(hpsb_lock);EXPORT_SYMBOL(hpsb_register_highlevel);EXPORT_SYMBOL(hpsb_unregister_highlevel);EXPORT_SYMBOL(hpsb_register_addrspace);EXPORT_SYMBOL(hpsb_listen_channel);EXPORT_SYMBOL(hpsb_unlisten_channel);EXPORT_SYMBOL(highlevel_read);EXPORT_SYMBOL(highlevel_write);EXPORT_SYMBOL(highlevel_lock);EXPORT_SYMBOL(highlevel_lock64);EXPORT_SYMBOL(highlevel_add_host);EXPORT_SYMBOL(highlevel_remove_host);EXPORT_SYMBOL(highlevel_host_reset);EXPORT_SYMBOL(highlevel_add_one_host);EXPORT_SYMBOL(hpsb_guid_get_entry);EXPORT_SYMBOL(hpsb_nodeid_get_entry);EXPORT_SYMBOL(hpsb_get_host_by_ne);EXPORT_SYMBOL(hpsb_guid_fill_packet);EXPORT_SYMBOL(hpsb_register_protocol);EXPORT_SYMBOL(hpsb_unregister_protocol);EXPORT_SYMBOL(hpsb_release_unit_directory);

⌨️ 快捷键说明

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